@antglobal/rlog-sdk 0.0.1755855517-dev.8 → 0.0.1779194445-dev.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.
Files changed (127) hide show
  1. package/README.md +192 -432
  2. package/dist/esm/index.d.ts +15 -41
  3. package/dist/esm/index.d.ts.map +1 -1
  4. package/dist/esm/index.js +101 -76
  5. package/dist/esm/lib/api.d.ts +10 -0
  6. package/dist/esm/lib/api.d.ts.map +1 -1
  7. package/dist/esm/lib/api.js +58 -35
  8. package/dist/esm/lib/config.d.ts +14 -16
  9. package/dist/esm/lib/config.d.ts.map +1 -1
  10. package/dist/esm/lib/config.js +61 -33
  11. package/dist/esm/lib/constants.d.ts +89 -0
  12. package/dist/esm/lib/constants.d.ts.map +1 -0
  13. package/dist/esm/lib/constants.js +145 -0
  14. package/dist/esm/lib/drive/indexeddb-adapt.d.ts +12 -0
  15. package/dist/esm/lib/drive/indexeddb-adapt.d.ts.map +1 -1
  16. package/dist/esm/lib/drive/indexeddb-adapt.js +190 -20
  17. package/dist/esm/lib/drive/localstorage-adapt.d.ts +12 -0
  18. package/dist/esm/lib/drive/localstorage-adapt.d.ts.map +1 -1
  19. package/dist/esm/lib/drive/localstorage-adapt.js +179 -36
  20. package/dist/esm/lib/drive/memory-adapt.d.ts +10 -2
  21. package/dist/esm/lib/drive/memory-adapt.d.ts.map +1 -1
  22. package/dist/esm/lib/drive/memory-adapt.js +118 -26
  23. package/dist/esm/lib/drive/safe-storage.d.ts +24 -0
  24. package/dist/esm/lib/drive/safe-storage.d.ts.map +1 -0
  25. package/dist/esm/lib/drive/safe-storage.js +96 -0
  26. package/dist/esm/lib/drive/storage-interface.d.ts +20 -0
  27. package/dist/esm/lib/drive/storage-interface.d.ts.map +1 -1
  28. package/dist/esm/lib/error-trigger.d.ts +73 -0
  29. package/dist/esm/lib/error-trigger.d.ts.map +1 -0
  30. package/dist/esm/lib/error-trigger.js +162 -0
  31. package/dist/esm/lib/error.d.ts +9 -0
  32. package/dist/esm/lib/error.d.ts.map +1 -1
  33. package/dist/esm/lib/error.js +70 -118
  34. package/dist/esm/lib/init.d.ts +0 -4
  35. package/dist/esm/lib/init.d.ts.map +1 -1
  36. package/dist/esm/lib/init.js +148 -47
  37. package/dist/esm/lib/logger.d.ts +27 -0
  38. package/dist/esm/lib/logger.d.ts.map +1 -0
  39. package/dist/esm/lib/logger.js +79 -0
  40. package/dist/esm/lib/net.d.ts +11 -0
  41. package/dist/esm/lib/net.d.ts.map +1 -1
  42. package/dist/esm/lib/net.js +264 -116
  43. package/dist/esm/lib/request.d.ts.map +1 -1
  44. package/dist/esm/lib/request.js +2 -2
  45. package/dist/esm/lib/router-monitor.d.ts.map +1 -1
  46. package/dist/esm/lib/router-monitor.js +135 -49
  47. package/dist/esm/lib/rrweb.d.ts.map +1 -1
  48. package/dist/esm/lib/rrweb.js +31 -24
  49. package/dist/esm/lib/storage-manager.d.ts +12 -0
  50. package/dist/esm/lib/storage-manager.d.ts.map +1 -1
  51. package/dist/esm/lib/storage-manager.js +129 -46
  52. package/dist/esm/lib/upload-worker-manager.d.ts +47 -0
  53. package/dist/esm/lib/upload-worker-manager.d.ts.map +1 -0
  54. package/dist/esm/lib/upload-worker-manager.js +559 -0
  55. package/dist/esm/lib/upload-worker.d.ts +58 -0
  56. package/dist/esm/lib/upload-worker.d.ts.map +1 -0
  57. package/dist/esm/lib/upload-worker.js +28 -0
  58. package/dist/esm/lib/uploader.d.ts +43 -0
  59. package/dist/esm/lib/uploader.d.ts.map +1 -1
  60. package/dist/esm/lib/uploader.js +464 -102
  61. package/dist/esm/lib/utils.d.ts +75 -0
  62. package/dist/esm/lib/utils.d.ts.map +1 -1
  63. package/dist/esm/lib/utils.js +268 -5
  64. package/dist/lib/index.d.ts +15 -41
  65. package/dist/lib/index.d.ts.map +1 -1
  66. package/dist/lib/index.js +89 -63
  67. package/dist/lib/lib/api.d.ts +10 -0
  68. package/dist/lib/lib/api.d.ts.map +1 -1
  69. package/dist/lib/lib/api.js +59 -35
  70. package/dist/lib/lib/config.d.ts +14 -16
  71. package/dist/lib/lib/config.d.ts.map +1 -1
  72. package/dist/lib/lib/config.js +63 -33
  73. package/dist/lib/lib/constants.d.ts +89 -0
  74. package/dist/lib/lib/constants.d.ts.map +1 -0
  75. package/dist/lib/lib/constants.js +151 -0
  76. package/dist/lib/lib/drive/indexeddb-adapt.d.ts +12 -0
  77. package/dist/lib/lib/drive/indexeddb-adapt.d.ts.map +1 -1
  78. package/dist/lib/lib/drive/indexeddb-adapt.js +191 -19
  79. package/dist/lib/lib/drive/localstorage-adapt.d.ts +12 -0
  80. package/dist/lib/lib/drive/localstorage-adapt.d.ts.map +1 -1
  81. package/dist/lib/lib/drive/localstorage-adapt.js +179 -36
  82. package/dist/lib/lib/drive/memory-adapt.d.ts +10 -2
  83. package/dist/lib/lib/drive/memory-adapt.d.ts.map +1 -1
  84. package/dist/lib/lib/drive/memory-adapt.js +117 -26
  85. package/dist/lib/lib/drive/safe-storage.d.ts +24 -0
  86. package/dist/lib/lib/drive/safe-storage.d.ts.map +1 -0
  87. package/dist/lib/lib/drive/safe-storage.js +102 -0
  88. package/dist/lib/lib/drive/storage-interface.d.ts +20 -0
  89. package/dist/lib/lib/drive/storage-interface.d.ts.map +1 -1
  90. package/dist/lib/lib/error-trigger.d.ts +73 -0
  91. package/dist/lib/lib/error-trigger.d.ts.map +1 -0
  92. package/dist/lib/lib/error-trigger.js +167 -0
  93. package/dist/lib/lib/error.d.ts +9 -0
  94. package/dist/lib/lib/error.d.ts.map +1 -1
  95. package/dist/lib/lib/error.js +73 -118
  96. package/dist/lib/lib/init.d.ts +0 -4
  97. package/dist/lib/lib/init.d.ts.map +1 -1
  98. package/dist/lib/lib/init.js +144 -43
  99. package/dist/lib/lib/logger.d.ts +27 -0
  100. package/dist/lib/lib/logger.d.ts.map +1 -0
  101. package/dist/lib/lib/logger.js +84 -0
  102. package/dist/lib/lib/net.d.ts +11 -0
  103. package/dist/lib/lib/net.d.ts.map +1 -1
  104. package/dist/lib/lib/net.js +268 -117
  105. package/dist/lib/lib/request.d.ts.map +1 -1
  106. package/dist/lib/lib/request.js +3 -3
  107. package/dist/lib/lib/router-monitor.d.ts.map +1 -1
  108. package/dist/lib/lib/router-monitor.js +136 -49
  109. package/dist/lib/lib/rrweb.d.ts.map +1 -1
  110. package/dist/lib/lib/rrweb.js +31 -23
  111. package/dist/lib/lib/storage-manager.d.ts +12 -0
  112. package/dist/lib/lib/storage-manager.d.ts.map +1 -1
  113. package/dist/lib/lib/storage-manager.js +130 -46
  114. package/dist/lib/lib/upload-worker-manager.d.ts +47 -0
  115. package/dist/lib/lib/upload-worker-manager.d.ts.map +1 -0
  116. package/dist/lib/lib/upload-worker-manager.js +570 -0
  117. package/dist/lib/lib/upload-worker.d.ts +58 -0
  118. package/dist/lib/lib/upload-worker.d.ts.map +1 -0
  119. package/dist/lib/lib/upload-worker.js +33 -0
  120. package/dist/lib/lib/uploader.d.ts +43 -0
  121. package/dist/lib/lib/uploader.d.ts.map +1 -1
  122. package/dist/lib/lib/uploader.js +468 -101
  123. package/dist/lib/lib/utils.d.ts +75 -0
  124. package/dist/lib/lib/utils.d.ts.map +1 -1
  125. package/dist/lib/lib/utils.js +276 -6
  126. package/dist/rlog-sdk.min.js +1 -1
  127. package/package.json +3 -2
@@ -13,9 +13,22 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
13
13
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
14
14
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
15
15
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
- // 根据业务需求配置的黑名单,监控和统计相关的接口
17
- var BLACK_HOST_NAME = ['arms', 'log', 'marmot-cloud.com', 'alipayobjects.com', 'renderpre.alipay.com', 'nemo-office.alipay.com', 'render.alipay.com'];
18
- var BLACK_PATH_NAME = ['r.png', 'dwcookieLogGet.do', 'track', 'spm', 'logstores', 'render', '.json', '.js', '.css', '.wasm', '.png', '.jpg', '.jpeg', '.weapp', '.data'];
16
+ import { record } from 'rrweb';
17
+ import { getConfig } from "./config";
18
+ import logger from "./logger";
19
+ import { BLACK_HOST_NAME, BLACK_PATH_NAME, HEADERS_TO_EXTRACT, EVENT_NETWORK_STATUS, EVENT_HTTP_SUCCESS, EVENT_HTTP_ERROR } from "./constants";
20
+
21
+ // 错误触发器引用(错误采集模式下由 init.ts 注入)
22
+ var errorTriggerInstance = null;
23
+
24
+ /**
25
+ * 设置网络模块的错误触发器实例
26
+ */
27
+ export function setNetErrorTrigger(trigger) {
28
+ errorTriggerInstance = trigger;
29
+ }
30
+
31
+ // 根据业务需求配置的黑名单和需要提取的响应头字段,已从 constants.ts 导入
19
32
 
20
33
  // 定义白名单URL列表和自定义请求头
21
34
  // 默认白名单为空,不抓取任何请求,需要用户手动配置
@@ -30,11 +43,8 @@ var blackListUrls = [
30
43
  // SDK日志上报接口地址
31
44
  var sdkLogEndpoint = null;
32
45
 
33
- // 需要提取的响应头字段
34
- var HEADERS_TO_EXTRACT = ['sky_trace_id', 'antbank-traceid'];
35
-
36
46
  // 辅助函数:规范化URL路径
37
- function normalizeUrl(url) {
47
+ export function normalizeUrl(url) {
38
48
  try {
39
49
  // 如果是完整URL,直接返回
40
50
  if (url.startsWith('http://') || url.startsWith('https://')) {
@@ -126,7 +136,7 @@ function isUrlInBlacklist(url, blacklist) {
126
136
  export function shouldRecordUrl(url) {
127
137
  // 如果URL在黑名单中,直接返回false
128
138
  if (isUrlInBlacklist(url, blackListUrls)) {
129
- // console.log(`[Blacklist] ${url} - Skipped (in blacklist)`);
139
+ // logger.log(`[Blacklist] ${url} - Skipped (in blacklist)`);
130
140
 
131
141
  return false;
132
142
  }
@@ -140,6 +150,28 @@ export function shouldRecordUrl(url) {
140
150
  return isUrlInWhitelist(url, whiteListUrls);
141
151
  }
142
152
 
153
+ // 网络状态变化事件处理
154
+ function handleOnline() {
155
+ try {
156
+ record.addCustomEvent(EVENT_NETWORK_STATUS, {
157
+ type: 'NETWORK_ONLINE',
158
+ timestamp: Date.now()
159
+ });
160
+ } catch (error) {
161
+ logger.warn('Failed to add NETWORK_ONLINE event (recording may have stopped)', error);
162
+ }
163
+ }
164
+ function handleOffline() {
165
+ try {
166
+ record.addCustomEvent(EVENT_NETWORK_STATUS, {
167
+ type: 'NETWORK_OFFLINE',
168
+ timestamp: Date.now()
169
+ });
170
+ } catch (error) {
171
+ logger.warn('Failed to add NETWORK_OFFLINE event (recording may have stopped)', error);
172
+ }
173
+ }
174
+
143
175
  // 存储原始方法
144
176
  var origOpen = XMLHttpRequest.prototype.open;
145
177
  var origSend = XMLHttpRequest.prototype.send;
@@ -149,164 +181,269 @@ var origFetch = window.fetch;
149
181
  var isHooked = false;
150
182
  export function watchXhr(r) {
151
183
  if (isHooked) {
152
- console.warn('RLog Network monitoring is already active');
184
+ logger.warn('Network monitoring is already active');
153
185
  return;
154
186
  }
155
- console.log('RLog Network monitoring is active');
156
187
  isHooked = true;
157
188
  // 拦截XMLHttpRequest
158
189
  XMLHttpRequest.prototype.open = function (method, url) {
159
190
  var async = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
160
191
  var username = arguments.length > 3 ? arguments[3] : undefined;
161
192
  var password = arguments.length > 4 ? arguments[4] : undefined;
162
- // 保存请求信息
163
- this._rlogRequest = {
164
- method: method,
165
- url: url.toString(),
166
- startTime: 0,
167
- endTime: 0
168
- };
193
+ try {
194
+ // 保存请求信息
195
+ this._rlogRequest = {
196
+ method: method,
197
+ url: url.toString(),
198
+ startTime: 0,
199
+ endTime: 0
200
+ };
201
+ } catch (error) {
202
+ logger.warn('Failed to save XHR request info:', error);
203
+ }
169
204
 
170
- // 调用原始open方法
205
+ // 调用原始open方法(不能被 SDK 异常影响)
171
206
  return origOpen.apply(this, [method, url, async, username, password]);
172
207
  };
173
208
  XMLHttpRequest.prototype.send = function (body) {
174
209
  var _this = this;
175
- var requestInfo = this._rlogRequest;
176
- requestInfo.startTime = Date.now();
177
- var method = requestInfo.method; // 从请求信息中获取method
178
-
179
- // 添加自定义请求头
180
- Object.entries(customHeaders).forEach(function (_ref) {
181
- var _ref2 = _slicedToArray(_ref, 2),
182
- key = _ref2[0],
183
- value = _ref2[1];
184
- _this.setRequestHeader(key, value);
185
- });
210
+ try {
211
+ var requestInfo = this._rlogRequest;
212
+ if (requestInfo) {
213
+ requestInfo.startTime = Date.now();
214
+
215
+ // 仅对白名单中的URL添加自定义请求头,避免跨域请求因非标准头触发CORS preflight失败
216
+ if (shouldRecordUrl(requestInfo.url)) {
217
+ try {
218
+ Object.entries(customHeaders).forEach(function (_ref) {
219
+ var _ref2 = _slicedToArray(_ref, 2),
220
+ key = _ref2[0],
221
+ value = _ref2[1];
222
+ _this.setRequestHeader(key, value);
223
+ });
224
+ } catch (error) {
225
+ logger.warn('Failed to set custom headers on XHR:', error);
226
+ }
227
+ }
186
228
 
187
- // 监听请求完成
188
- this.addEventListener('load', function () {
189
- var _this2 = this;
190
- requestInfo.endTime = Date.now();
191
- // 检查是否应该记录该URL
192
- if (shouldRecordUrl(requestInfo.url)) {
193
- // 提取指定响应头字段
194
- var responseHeaders = {};
195
- HEADERS_TO_EXTRACT.forEach(function (headerName) {
229
+ // 监听请求完成
230
+ this.addEventListener('load', function () {
231
+ var _this2 = this;
196
232
  try {
197
- var value = _this2.getResponseHeader(headerName);
198
- if (value) {
199
- responseHeaders[headerName] = value;
233
+ requestInfo.endTime = Date.now();
234
+ // 检查是否应该记录该URL
235
+ if (shouldRecordUrl(requestInfo.url)) {
236
+ // 提取指定响应头字段
237
+ var responseHeaders = {};
238
+ HEADERS_TO_EXTRACT.forEach(function (headerName) {
239
+ try {
240
+ var value = _this2.getResponseHeader(headerName);
241
+ if (value) {
242
+ responseHeaders[headerName] = value;
243
+ }
244
+ } catch (error) {
245
+ // 忽略无法访问的响应头(如CORS限制)
246
+ }
247
+ });
248
+ try {
249
+ r.addCustomEvent(EVENT_HTTP_SUCCESS, _objectSpread(_objectSpread({}, requestInfo), {}, {
250
+ dur: requestInfo.endTime - requestInfo.startTime,
251
+ responseHeaders: responseHeaders,
252
+ pagePath: window.location.href
253
+ }));
254
+ } catch (error) {
255
+ // 忽略录制已停止时的异常
256
+ }
257
+ }
258
+
259
+ // 错误采集模式下:检查 HTTP 状态码是否为错误
260
+ if (errorTriggerInstance) {
261
+ var _config$errorCapture$, _config$errorCapture;
262
+ var config = getConfig();
263
+ var httpErrorThreshold = (_config$errorCapture$ = (_config$errorCapture = config.errorCapture) === null || _config$errorCapture === void 0 ? void 0 : _config$errorCapture.httpErrorThreshold) !== null && _config$errorCapture$ !== void 0 ? _config$errorCapture$ : 400;
264
+ if (this.status >= httpErrorThreshold) {
265
+ errorTriggerInstance.onError({
266
+ type: 'http',
267
+ message: "XHR ".concat(requestInfo.method, " ").concat(requestInfo.url, " responded with status ").concat(this.status),
268
+ timestamp: Date.now(),
269
+ detail: {
270
+ url: requestInfo.url,
271
+ method: requestInfo.method,
272
+ status: this.status
273
+ }
274
+ });
275
+ }
200
276
  }
201
277
  } catch (error) {
202
- // 忽略无法访问的响应头(如CORS限制)
203
- console.warn("\u65E0\u6CD5\u83B7\u53D6\u54CD\u5E94\u5934 ".concat(headerName, ":"), error);
278
+ logger.warn('Error in XHR load handler:', error);
204
279
  }
205
280
  });
206
- try {
207
- r.addCustomEvent('http-success', _objectSpread(_objectSpread({}, requestInfo), {}, {
208
- dur: requestInfo.endTime - requestInfo.startTime,
209
- responseHeaders: responseHeaders,
210
- pagePath: window.location.href
211
- }));
212
- } catch (error) {
213
- // 忽略录制已停止时的异常
214
- console.warn('Failed to add custom event (recording may have stopped):', error);
215
- }
216
- }
217
- });
218
281
 
219
- // 监听请求错误
220
- this.addEventListener('error', function () {
221
- try {
222
- r.addCustomEvent('http-error', _objectSpread(_objectSpread({}, requestInfo), {}, {
223
- dur: requestInfo.endTime - requestInfo.startTime,
224
- pagePath: window.location.href
225
- }));
226
- } catch (error) {
227
- // 忽略录制已停止时的异常
228
- console.warn('Failed to add custom event (recording may have stopped):', error);
282
+ // 监听请求错误
283
+ this.addEventListener('error', function () {
284
+ try {
285
+ r.addCustomEvent(EVENT_HTTP_ERROR, _objectSpread(_objectSpread({}, requestInfo), {}, {
286
+ dur: requestInfo.endTime - requestInfo.startTime,
287
+ pagePath: window.location.href
288
+ }));
289
+ } catch (error) {
290
+ // 忽略录制已停止时的异常
291
+ }
292
+
293
+ // 错误采集模式下:XHR 网络错误触发
294
+ try {
295
+ if (errorTriggerInstance) {
296
+ errorTriggerInstance.onError({
297
+ type: 'http',
298
+ message: "XHR ".concat(requestInfo.method, " ").concat(requestInfo.url, " network error"),
299
+ timestamp: Date.now(),
300
+ detail: {
301
+ url: requestInfo.url,
302
+ method: requestInfo.method
303
+ }
304
+ });
305
+ }
306
+ } catch (error) {
307
+ logger.warn('Error in XHR error trigger:', error);
308
+ }
309
+ });
229
310
  }
230
- });
311
+ } catch (error) {
312
+ logger.warn('Error in XHR send hook:', error);
313
+ }
231
314
 
232
- // 调用原始send方法
315
+ // 调用原始send方法(不能被 SDK 异常影响)
233
316
  return origSend.apply(this, [body]);
234
317
  };
235
318
 
236
319
  // 拦截fetch API
237
320
  window.fetch = /*#__PURE__*/function () {
238
321
  var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(input, init) {
239
- var url, method, startTime, newInit, response, endTime, responseHeaders;
322
+ var url, method, startTime, actualInit, response, endTime, responseHeaders, _config$errorCapture$2, _config$errorCapture2, config, httpErrorThreshold;
240
323
  return _regeneratorRuntime().wrap(function _callee$(_context) {
241
324
  while (1) switch (_context.prev = _context.next) {
242
325
  case 0:
326
+ _context.prev = 0;
243
327
  url = input instanceof Request ? input.url : input.toString();
244
- method = (init === null || init === void 0 ? void 0 : init.method) || (input instanceof Request ? input.method : 'GET').toUpperCase(); // 统一转大写
245
- startTime = Date.now();
246
- _context.prev = 3;
247
- // 创建新的请求配置
248
- newInit = _objectSpread({}, init); // 添加自定义请求头
249
- newInit.headers = _objectSpread(_objectSpread({}, (init === null || init === void 0 ? void 0 : init.headers) || {}), customHeaders);
328
+ method = (init === null || init === void 0 ? void 0 : init.method) || (input instanceof Request ? input.method : 'GET').toUpperCase();
250
329
  _context.next = 8;
251
- return origFetch(input, newInit);
330
+ break;
331
+ case 5:
332
+ _context.prev = 5;
333
+ _context.t0 = _context["catch"](0);
334
+ return _context.abrupt("return", origFetch(input, init));
252
335
  case 8:
253
- response = _context.sent;
254
- endTime = Date.now(); // 检查是否应该记录该URL
255
- if (shouldRecordUrl(url)) {
256
- console.log("[Fetch] ".concat(method, " ").concat(url, " - ").concat(endTime - startTime, "ms"));
257
-
258
- // 提取指定响应头字段
259
- responseHeaders = {};
260
- HEADERS_TO_EXTRACT.forEach(function (headerName) {
261
- try {
262
- var value = response.headers.get(headerName);
263
- if (value) {
264
- responseHeaders[headerName] = value;
265
- }
266
- } catch (error) {
267
- // 忽略无法访问的响应头(如CORS限制)
268
- console.warn("\u65E0\u6CD5\u83B7\u53D6\u54CD\u5E94\u5934 ".concat(headerName, ":"), error);
269
- }
270
- });
271
- try {
272
- r.addCustomEvent('http-success', {
273
- url: url,
274
- method: method,
275
- dur: endTime - startTime,
276
- responseHeaders: responseHeaders,
277
- pagePath: window.location.href
336
+ startTime = Date.now(); // 构建请求参数,仅对白名单 URL 添加自定义头
337
+ actualInit = init;
338
+ try {
339
+ if (shouldRecordUrl(url) && Object.keys(customHeaders).length > 0) {
340
+ actualInit = _objectSpread(_objectSpread({}, init), {}, {
341
+ headers: _objectSpread(_objectSpread({}, (init === null || init === void 0 ? void 0 : init.headers) || {}), customHeaders)
278
342
  });
279
- } catch (error) {
280
- // 忽略录制已停止时的异常
281
- console.warn('Failed to add custom event (recording may have stopped):', error);
282
343
  }
344
+ } catch (error) {
345
+ logger.warn('Failed to add custom headers on Fetch:', error);
346
+ actualInit = init;
283
347
  }
284
- return _context.abrupt("return", response);
348
+ _context.prev = 11;
349
+ _context.next = 14;
350
+ return origFetch(input, actualInit);
285
351
  case 14:
286
- _context.prev = 14;
287
- _context.t0 = _context["catch"](3);
288
- console.error("[Fetch Error] ".concat(method, " ").concat(url), _context.t0);
352
+ response = _context.sent;
353
+ _context.next = 22;
354
+ break;
355
+ case 17:
356
+ _context.prev = 17;
357
+ _context.t1 = _context["catch"](11);
358
+ // Fetch 网络错误:先做 SDK 记录,再原样抛出给业务
289
359
  try {
290
- r.addCustomEvent('http-error', {
360
+ r.addCustomEvent(EVENT_HTTP_ERROR, {
291
361
  url: url,
292
362
  method: method,
293
363
  pagePath: window.location.href
294
364
  });
295
- } catch (eventError) {
296
- // 忽略录制已停止时的异常
297
- console.warn('Failed to add custom event (recording may have stopped):', eventError);
365
+ } catch (_) {
366
+ // 忽略录制异常
367
+ }
368
+ try {
369
+ if (errorTriggerInstance) {
370
+ errorTriggerInstance.onError({
371
+ type: 'http',
372
+ message: "Fetch ".concat(method, " ").concat(url, " network error"),
373
+ timestamp: Date.now(),
374
+ detail: {
375
+ url: url,
376
+ method: method,
377
+ error: String(_context.t1)
378
+ }
379
+ });
380
+ }
381
+ } catch (_) {
382
+ // 忽略错误触发器异常
383
+ }
384
+ throw _context.t1;
385
+ case 22:
386
+ // 请求成功后的 SDK 记录逻辑,全部 try/catch 保护
387
+ try {
388
+ endTime = Date.now();
389
+ if (shouldRecordUrl(url)) {
390
+ responseHeaders = {};
391
+ HEADERS_TO_EXTRACT.forEach(function (headerName) {
392
+ try {
393
+ var value = response.headers.get(headerName);
394
+ if (value) {
395
+ responseHeaders[headerName] = value;
396
+ }
397
+ } catch (_) {
398
+ // 忽略无法访问的响应头
399
+ }
400
+ });
401
+ try {
402
+ r.addCustomEvent(EVENT_HTTP_SUCCESS, {
403
+ url: url,
404
+ method: method,
405
+ dur: endTime - startTime,
406
+ responseHeaders: responseHeaders,
407
+ pagePath: window.location.href
408
+ });
409
+ } catch (_) {
410
+ // 忽略录制异常
411
+ }
412
+ }
413
+ if (errorTriggerInstance) {
414
+ config = getConfig();
415
+ httpErrorThreshold = (_config$errorCapture$2 = (_config$errorCapture2 = config.errorCapture) === null || _config$errorCapture2 === void 0 ? void 0 : _config$errorCapture2.httpErrorThreshold) !== null && _config$errorCapture$2 !== void 0 ? _config$errorCapture$2 : 400;
416
+ if (response.status >= httpErrorThreshold) {
417
+ errorTriggerInstance.onError({
418
+ type: 'http',
419
+ message: "Fetch ".concat(method, " ").concat(url, " responded with status ").concat(response.status),
420
+ timestamp: Date.now(),
421
+ detail: {
422
+ url: url,
423
+ method: method,
424
+ status: response.status
425
+ }
426
+ });
427
+ }
428
+ }
429
+ } catch (error) {
430
+ logger.warn('Error in Fetch success handler:', error);
298
431
  }
299
- throw _context.t0;
300
- case 19:
432
+ return _context.abrupt("return", response);
433
+ case 24:
301
434
  case "end":
302
435
  return _context.stop();
303
436
  }
304
- }, _callee, null, [[3, 14]]);
437
+ }, _callee, null, [[0, 5], [11, 17]]);
305
438
  }));
306
439
  return function (_x, _x2) {
307
440
  return _ref3.apply(this, arguments);
308
441
  };
309
442
  }();
443
+
444
+ // 监听网络连接状态变化
445
+ window.addEventListener('online', handleOnline);
446
+ window.addEventListener('offline', handleOffline);
310
447
  }
311
448
 
312
449
  // 恢复原始方法
@@ -320,8 +457,11 @@ export function restoreXhr() {
320
457
  if (origFetch) {
321
458
  window.fetch = origFetch;
322
459
  }
460
+
461
+ // 移除网络状态监听器
462
+ window.removeEventListener('online', handleOnline);
463
+ window.removeEventListener('offline', handleOffline);
323
464
  isHooked = false;
324
- console.log('RLog network monitoring restored');
325
465
  }
326
466
 
327
467
  // 导出配置方法
@@ -368,7 +508,7 @@ export function setSdkLogEndpoint(endpoint) {
368
508
  sdkLogEndpoint = endpoint;
369
509
 
370
510
  // 规范化endpoint路径,确保相对路径也能正确匹配
371
- var normalizedEndpoint = endpoint.startsWith('/') ? endpoint : '/' + endpoint;
511
+ var normalizedEndpoint = normalizeUrl(endpoint);
372
512
 
373
513
  // 自动将SDK日志上报接口加入黑名单,避免循环上报
374
514
  // 同时添加原始路径和规范化路径,确保兼容性
@@ -398,4 +538,12 @@ export function getSdkLogEndpoint() {
398
538
  */
399
539
  export function setCustomHeaders(headers) {
400
540
  Object.assign(customHeaders, headers);
541
+ }
542
+
543
+ /**
544
+ * 获取当前设置的自定义请求头
545
+ * @returns 当前自定义请求头的副本
546
+ */
547
+ export function getCustomHeaders() {
548
+ return _objectSpread({}, customHeaders);
401
549
  }
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/lib/request.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC;IACV,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwE1F;AAED;;;;;GAKG;AACH,wBAAsB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,MAAM,CAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE/G;AAED;;;;;;GAMG;AACH,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEnH"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/lib/request.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC;IACV,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwE1F;AAED;;;;;GAKG;AACH,wBAAsB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,MAAM,CAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE/G;AAED;;;;;;GAMG;AACH,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEnH"}
@@ -8,7 +8,7 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
8
8
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
9
9
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
10
10
  // 简单的 XMLHttpRequest 封装,提供更好的兼容性
11
-
11
+ import { REQUEST_TIMEOUT } from "./constants";
12
12
  /**
13
13
  * 发送 HTTP 请求
14
14
  * @param url 请求地址
@@ -40,7 +40,7 @@ function _request() {
40
40
  headers = _options$headers === void 0 ? {} : _options$headers,
41
41
  body = options.body,
42
42
  _options$timeout = options.timeout,
43
- timeout = _options$timeout === void 0 ? 10000 : _options$timeout;
43
+ timeout = _options$timeout === void 0 ? REQUEST_TIMEOUT : _options$timeout;
44
44
  var xhr = new XMLHttpRequest();
45
45
 
46
46
  // 设置超时
@@ -1 +1 @@
1
- {"version":3,"file":"router-monitor.d.ts","sourceRoot":"","sources":["../../../src/lib/router-monitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,UAAU,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2JD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,eAAe,CAAC,GAAG,IAAI,CAwB3E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,QAmCpE;AAED;;GAEG;AACH,wBAAgB,mBAAmB;;;;EAMlC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,QAG1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,SAyBhC"}
1
+ {"version":3,"file":"router-monitor.d.ts","sourceRoot":"","sources":["../../../src/lib/router-monitor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,UAAU,CAAC;AAKrD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAoJD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,eAAe,CAAC,GAAG,IAAI,CAuB3E;AAuFD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,eAAe,CAAC,QA0CpE;AAED;;GAEG;AACH,wBAAgB,mBAAmB;;;;EAMlC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,QAG1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,SA4BhC"}