@antglobal/rlog-sdk 0.0.1755855517-dev.9 → 0.0.1781493462-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -432
- package/dist/esm/index.d.ts +15 -41
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +101 -76
- package/dist/esm/lib/api.d.ts +10 -0
- package/dist/esm/lib/api.d.ts.map +1 -1
- package/dist/esm/lib/api.js +60 -26
- package/dist/esm/lib/config.d.ts +14 -7
- package/dist/esm/lib/config.d.ts.map +1 -1
- package/dist/esm/lib/config.js +63 -35
- package/dist/esm/lib/constants.d.ts +97 -0
- package/dist/esm/lib/constants.d.ts.map +1 -0
- package/dist/esm/lib/constants.js +159 -0
- package/dist/esm/lib/drive/indexeddb-adapt.d.ts +12 -0
- package/dist/esm/lib/drive/indexeddb-adapt.d.ts.map +1 -1
- package/dist/esm/lib/drive/indexeddb-adapt.js +190 -20
- package/dist/esm/lib/drive/localstorage-adapt.d.ts +12 -0
- package/dist/esm/lib/drive/localstorage-adapt.d.ts.map +1 -1
- package/dist/esm/lib/drive/localstorage-adapt.js +179 -36
- package/dist/esm/lib/drive/memory-adapt.d.ts +10 -2
- package/dist/esm/lib/drive/memory-adapt.d.ts.map +1 -1
- package/dist/esm/lib/drive/memory-adapt.js +118 -26
- package/dist/esm/lib/drive/safe-storage.d.ts +24 -0
- package/dist/esm/lib/drive/safe-storage.d.ts.map +1 -0
- package/dist/esm/lib/drive/safe-storage.js +96 -0
- package/dist/esm/lib/drive/storage-interface.d.ts +20 -0
- package/dist/esm/lib/drive/storage-interface.d.ts.map +1 -1
- package/dist/esm/lib/error-trigger.d.ts +73 -0
- package/dist/esm/lib/error-trigger.d.ts.map +1 -0
- package/dist/esm/lib/error-trigger.js +162 -0
- package/dist/esm/lib/error.d.ts +9 -0
- package/dist/esm/lib/error.d.ts.map +1 -1
- package/dist/esm/lib/error.js +70 -118
- package/dist/esm/lib/init.d.ts +0 -4
- package/dist/esm/lib/init.d.ts.map +1 -1
- package/dist/esm/lib/init.js +148 -47
- package/dist/esm/lib/logger.d.ts +27 -0
- package/dist/esm/lib/logger.d.ts.map +1 -0
- package/dist/esm/lib/logger.js +79 -0
- package/dist/esm/lib/net.d.ts +11 -0
- package/dist/esm/lib/net.d.ts.map +1 -1
- package/dist/esm/lib/net.js +264 -119
- package/dist/esm/lib/request.d.ts.map +1 -1
- package/dist/esm/lib/request.js +2 -2
- package/dist/esm/lib/router-monitor.d.ts.map +1 -1
- package/dist/esm/lib/router-monitor.js +135 -49
- package/dist/esm/lib/rrweb.d.ts.map +1 -1
- package/dist/esm/lib/rrweb.js +41 -30
- package/dist/esm/lib/sign.d.ts +36 -0
- package/dist/esm/lib/sign.d.ts.map +1 -0
- package/dist/esm/lib/sign.js +393 -0
- package/dist/esm/lib/storage-manager.d.ts +12 -0
- package/dist/esm/lib/storage-manager.d.ts.map +1 -1
- package/dist/esm/lib/storage-manager.js +129 -46
- package/dist/esm/lib/upload-worker-manager.d.ts +47 -0
- package/dist/esm/lib/upload-worker-manager.d.ts.map +1 -0
- package/dist/esm/lib/upload-worker-manager.js +570 -0
- package/dist/esm/lib/upload-worker.d.ts +58 -0
- package/dist/esm/lib/upload-worker.d.ts.map +1 -0
- package/dist/esm/lib/upload-worker.js +28 -0
- package/dist/esm/lib/uploader.d.ts +43 -0
- package/dist/esm/lib/uploader.d.ts.map +1 -1
- package/dist/esm/lib/uploader.js +464 -102
- package/dist/esm/lib/utils.d.ts +80 -0
- package/dist/esm/lib/utils.d.ts.map +1 -1
- package/dist/esm/lib/utils.js +276 -5
- package/dist/lib/index.d.ts +15 -41
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +89 -63
- package/dist/lib/lib/api.d.ts +10 -0
- package/dist/lib/lib/api.d.ts.map +1 -1
- package/dist/lib/lib/api.js +61 -26
- package/dist/lib/lib/config.d.ts +14 -7
- package/dist/lib/lib/config.d.ts.map +1 -1
- package/dist/lib/lib/config.js +65 -35
- package/dist/lib/lib/constants.d.ts +97 -0
- package/dist/lib/lib/constants.d.ts.map +1 -0
- package/dist/lib/lib/constants.js +165 -0
- package/dist/lib/lib/drive/indexeddb-adapt.d.ts +12 -0
- package/dist/lib/lib/drive/indexeddb-adapt.d.ts.map +1 -1
- package/dist/lib/lib/drive/indexeddb-adapt.js +191 -19
- package/dist/lib/lib/drive/localstorage-adapt.d.ts +12 -0
- package/dist/lib/lib/drive/localstorage-adapt.d.ts.map +1 -1
- package/dist/lib/lib/drive/localstorage-adapt.js +179 -36
- package/dist/lib/lib/drive/memory-adapt.d.ts +10 -2
- package/dist/lib/lib/drive/memory-adapt.d.ts.map +1 -1
- package/dist/lib/lib/drive/memory-adapt.js +117 -26
- package/dist/lib/lib/drive/safe-storage.d.ts +24 -0
- package/dist/lib/lib/drive/safe-storage.d.ts.map +1 -0
- package/dist/lib/lib/drive/safe-storage.js +102 -0
- package/dist/lib/lib/drive/storage-interface.d.ts +20 -0
- package/dist/lib/lib/drive/storage-interface.d.ts.map +1 -1
- package/dist/lib/lib/error-trigger.d.ts +73 -0
- package/dist/lib/lib/error-trigger.d.ts.map +1 -0
- package/dist/lib/lib/error-trigger.js +167 -0
- package/dist/lib/lib/error.d.ts +9 -0
- package/dist/lib/lib/error.d.ts.map +1 -1
- package/dist/lib/lib/error.js +73 -118
- package/dist/lib/lib/init.d.ts +0 -4
- package/dist/lib/lib/init.d.ts.map +1 -1
- package/dist/lib/lib/init.js +144 -43
- package/dist/lib/lib/logger.d.ts +27 -0
- package/dist/lib/lib/logger.d.ts.map +1 -0
- package/dist/lib/lib/logger.js +84 -0
- package/dist/lib/lib/net.d.ts +11 -0
- package/dist/lib/lib/net.d.ts.map +1 -1
- package/dist/lib/lib/net.js +268 -120
- package/dist/lib/lib/request.d.ts.map +1 -1
- package/dist/lib/lib/request.js +3 -3
- package/dist/lib/lib/router-monitor.d.ts.map +1 -1
- package/dist/lib/lib/router-monitor.js +136 -49
- package/dist/lib/lib/rrweb.d.ts.map +1 -1
- package/dist/lib/lib/rrweb.js +41 -31
- package/dist/lib/lib/sign.d.ts +36 -0
- package/dist/lib/lib/sign.d.ts.map +1 -0
- package/dist/lib/lib/sign.js +398 -0
- package/dist/lib/lib/storage-manager.d.ts +12 -0
- package/dist/lib/lib/storage-manager.d.ts.map +1 -1
- package/dist/lib/lib/storage-manager.js +130 -46
- package/dist/lib/lib/upload-worker-manager.d.ts +47 -0
- package/dist/lib/lib/upload-worker-manager.d.ts.map +1 -0
- package/dist/lib/lib/upload-worker-manager.js +581 -0
- package/dist/lib/lib/upload-worker.d.ts +58 -0
- package/dist/lib/lib/upload-worker.d.ts.map +1 -0
- package/dist/lib/lib/upload-worker.js +33 -0
- package/dist/lib/lib/uploader.d.ts +43 -0
- package/dist/lib/lib/uploader.d.ts.map +1 -1
- package/dist/lib/lib/uploader.js +468 -101
- package/dist/lib/lib/utils.d.ts +80 -0
- package/dist/lib/lib/utils.d.ts.map +1 -1
- package/dist/lib/lib/utils.js +284 -6
- package/dist/rlog-sdk.min.js +1 -1
- package/package.json +5 -4
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
-
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
3
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
4
|
-
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; }
|
|
5
2
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
6
3
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
7
4
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -14,6 +11,8 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
14
11
|
|
|
15
12
|
import { record } from 'rrweb';
|
|
16
13
|
import { getConfig } from "./config";
|
|
14
|
+
import logger from "./logger";
|
|
15
|
+
import { EVENT_ROUTE_CHANGE, EVENT_PAGE_LIFECYCLE } from "./constants";
|
|
17
16
|
|
|
18
17
|
// 路由变化事件类型
|
|
19
18
|
|
|
@@ -29,39 +28,18 @@ var originalReplaceState = null;
|
|
|
29
28
|
* 获取当前路由
|
|
30
29
|
*/
|
|
31
30
|
function getCurrentRoute() {
|
|
32
|
-
var _routerConfig;
|
|
33
31
|
if (typeof window === 'undefined') return '';
|
|
34
32
|
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// 应用自定义匹配规则
|
|
39
|
-
if ((_routerConfig = routerConfig) !== null && _routerConfig !== void 0 && _routerConfig.customMatchers) {
|
|
40
|
-
var _iterator = _createForOfIteratorHelper(routerConfig.customMatchers),
|
|
41
|
-
_step;
|
|
42
|
-
try {
|
|
43
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
44
|
-
var matcher = _step.value;
|
|
45
|
-
var pattern = typeof matcher.pattern === 'string' ? new RegExp(matcher.pattern) : matcher.pattern;
|
|
46
|
-
if (pattern.test(fullPath)) {
|
|
47
|
-
return matcher.name || fullPath;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
} catch (err) {
|
|
51
|
-
_iterator.e(err);
|
|
52
|
-
} finally {
|
|
53
|
-
_iterator.f();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return fullPath;
|
|
33
|
+
// 使用完整路径
|
|
34
|
+
return window.location.pathname + window.location.search + window.location.hash;
|
|
57
35
|
}
|
|
58
36
|
|
|
59
37
|
/**
|
|
60
38
|
* 检查路由是否应该被忽略
|
|
61
39
|
*/
|
|
62
40
|
function shouldIgnoreRoute(route) {
|
|
63
|
-
var
|
|
64
|
-
if (!((
|
|
41
|
+
var _routerConfig;
|
|
42
|
+
if (!((_routerConfig = routerConfig) !== null && _routerConfig !== void 0 && _routerConfig.ignoreRoutes)) return false;
|
|
65
43
|
return routerConfig.ignoreRoutes.some(function (pattern) {
|
|
66
44
|
if (typeof pattern === 'string') {
|
|
67
45
|
return route.includes(pattern);
|
|
@@ -77,8 +55,8 @@ function shouldIgnoreRoute(route) {
|
|
|
77
55
|
* 上报路由变化事件
|
|
78
56
|
*/
|
|
79
57
|
function reportRouteChange(from, to, method) {
|
|
80
|
-
var
|
|
81
|
-
if (!((
|
|
58
|
+
var _routerConfig2;
|
|
59
|
+
if (!((_routerConfig2 = routerConfig) !== null && _routerConfig2 !== void 0 && _routerConfig2.enable) || shouldIgnoreRoute(to)) {
|
|
82
60
|
return;
|
|
83
61
|
}
|
|
84
62
|
var event = {
|
|
@@ -89,16 +67,19 @@ function reportRouteChange(from, to, method) {
|
|
|
89
67
|
timestamp: Date.now()
|
|
90
68
|
};
|
|
91
69
|
|
|
70
|
+
// 更新当前路由
|
|
71
|
+
currentRoute = to;
|
|
72
|
+
|
|
92
73
|
// 计算页面停留时间
|
|
93
74
|
if (routerConfig.trackPageStayTime && from) {
|
|
94
75
|
event.duration = Date.now() - routeStartTime;
|
|
95
76
|
}
|
|
96
77
|
try {
|
|
97
78
|
// 使用 rrweb 的自定义事件功能上报
|
|
98
|
-
record.addCustomEvent(
|
|
79
|
+
record.addCustomEvent(EVENT_ROUTE_CHANGE, event);
|
|
99
80
|
} catch (error) {
|
|
100
81
|
// 忽略录制已停止时的异常
|
|
101
|
-
|
|
82
|
+
logger.warn('Failed to add custom event (recording may have stopped)', error);
|
|
102
83
|
}
|
|
103
84
|
// 重置计时器
|
|
104
85
|
routeStartTime = Date.now();
|
|
@@ -114,28 +95,38 @@ function listenToHistoryChanges() {
|
|
|
114
95
|
|
|
115
96
|
// 重写 pushState
|
|
116
97
|
window.history.pushState = function () {
|
|
117
|
-
var from = getCurrentRoute();
|
|
118
98
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
119
99
|
args[_key] = arguments[_key];
|
|
120
100
|
}
|
|
101
|
+
// 先调用原始方法,确保业务路由跳转不受影响
|
|
121
102
|
var result = originalPushState.apply(this, args);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
103
|
+
try {
|
|
104
|
+
var to = getCurrentRoute();
|
|
105
|
+
var from = currentRoute;
|
|
106
|
+
if (from !== to) {
|
|
107
|
+
reportRouteChange(from, to, 'pushState');
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
logger.warn('Error in pushState hook:', error);
|
|
125
111
|
}
|
|
126
112
|
return result;
|
|
127
113
|
};
|
|
128
114
|
|
|
129
115
|
// 重写 replaceState
|
|
130
116
|
window.history.replaceState = function () {
|
|
131
|
-
var from = getCurrentRoute();
|
|
132
117
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
133
118
|
args[_key2] = arguments[_key2];
|
|
134
119
|
}
|
|
120
|
+
// 先调用原始方法,确保业务路由跳转不受影响
|
|
135
121
|
var result = originalReplaceState.apply(this, args);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
122
|
+
try {
|
|
123
|
+
var to = getCurrentRoute();
|
|
124
|
+
var from = currentRoute;
|
|
125
|
+
if (from !== to) {
|
|
126
|
+
reportRouteChange(from, to, 'replaceState');
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
logger.warn('Error in replaceState hook:', error);
|
|
139
130
|
}
|
|
140
131
|
return result;
|
|
141
132
|
};
|
|
@@ -171,15 +162,14 @@ function handleHashChange() {
|
|
|
171
162
|
* @param config 新的配置对象
|
|
172
163
|
*/
|
|
173
164
|
export function updateRouterConfig(config) {
|
|
174
|
-
var _defaultConfig$enable, _defaultConfig$trackH, _defaultConfig$trackH2, _defaultConfig$trackP, _defaultConfig$ignore
|
|
165
|
+
var _defaultConfig$enable, _defaultConfig$trackH, _defaultConfig$trackH2, _defaultConfig$trackP, _defaultConfig$ignore;
|
|
175
166
|
var defaultConfig = getConfig().routerMonitor || {};
|
|
176
167
|
var newConfig = _objectSpread({
|
|
177
168
|
enable: (_defaultConfig$enable = defaultConfig.enable) !== null && _defaultConfig$enable !== void 0 ? _defaultConfig$enable : false,
|
|
178
169
|
trackHashChange: (_defaultConfig$trackH = defaultConfig.trackHashChange) !== null && _defaultConfig$trackH !== void 0 ? _defaultConfig$trackH : true,
|
|
179
170
|
trackHistoryChange: (_defaultConfig$trackH2 = defaultConfig.trackHistoryChange) !== null && _defaultConfig$trackH2 !== void 0 ? _defaultConfig$trackH2 : true,
|
|
180
171
|
trackPageStayTime: (_defaultConfig$trackP = defaultConfig.trackPageStayTime) !== null && _defaultConfig$trackP !== void 0 ? _defaultConfig$trackP : true,
|
|
181
|
-
ignoreRoutes: (_defaultConfig$ignore = defaultConfig.ignoreRoutes) !== null && _defaultConfig$ignore !== void 0 ? _defaultConfig$ignore : []
|
|
182
|
-
customMatchers: (_defaultConfig$custom = defaultConfig.customMatchers) !== null && _defaultConfig$custom !== void 0 ? _defaultConfig$custom : []
|
|
172
|
+
ignoreRoutes: (_defaultConfig$ignore = defaultConfig.ignoreRoutes) !== null && _defaultConfig$ignore !== void 0 ? _defaultConfig$ignore : []
|
|
183
173
|
}, config || {});
|
|
184
174
|
|
|
185
175
|
// 如果配置发生变化,重新初始化
|
|
@@ -194,11 +184,96 @@ export function updateRouterConfig(config) {
|
|
|
194
184
|
}
|
|
195
185
|
}
|
|
196
186
|
|
|
187
|
+
/**
|
|
188
|
+
* 处理页面加载事件
|
|
189
|
+
*/
|
|
190
|
+
function handlePageLoad() {
|
|
191
|
+
try {
|
|
192
|
+
record.addCustomEvent(EVENT_PAGE_LIFECYCLE, {
|
|
193
|
+
type: 'PAGE_LOAD',
|
|
194
|
+
url: window.location.href,
|
|
195
|
+
timestamp: Date.now()
|
|
196
|
+
});
|
|
197
|
+
} catch (error) {
|
|
198
|
+
logger.warn('Failed to add PAGE_LOAD event (recording may have stopped)', error);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* 处理页面卸载事件
|
|
204
|
+
*/
|
|
205
|
+
function handlePageUnload() {
|
|
206
|
+
try {
|
|
207
|
+
record.addCustomEvent(EVENT_PAGE_LIFECYCLE, {
|
|
208
|
+
type: 'PAGE_UNLOAD',
|
|
209
|
+
url: window.location.href,
|
|
210
|
+
timestamp: Date.now()
|
|
211
|
+
});
|
|
212
|
+
} catch (error) {
|
|
213
|
+
logger.warn('Failed to add PAGE_UNLOAD event (recording may have stopped)', error);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* 处理页面隐藏事件(移动端友好,替代 beforeunload)
|
|
219
|
+
* pagehide 在移动端浏览器中比 beforeunload 更可靠
|
|
220
|
+
*/
|
|
221
|
+
function handlePageHide(event) {
|
|
222
|
+
try {
|
|
223
|
+
record.addCustomEvent(EVENT_PAGE_LIFECYCLE, {
|
|
224
|
+
type: 'PAGE_HIDE',
|
|
225
|
+
url: window.location.href,
|
|
226
|
+
timestamp: Date.now(),
|
|
227
|
+
persisted: event.persisted // 页面是否进入 bfcache
|
|
228
|
+
});
|
|
229
|
+
} catch (error) {
|
|
230
|
+
logger.warn('Failed to add PAGE_HIDE event (recording may have stopped)', error);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* 处理页面显示事件(移动端友好,支持 bfcache 恢复检测)
|
|
236
|
+
* pageshow 在页面从 bfcache 恢复时也会触发
|
|
237
|
+
*/
|
|
238
|
+
function handlePageShow(event) {
|
|
239
|
+
try {
|
|
240
|
+
record.addCustomEvent(EVENT_PAGE_LIFECYCLE, {
|
|
241
|
+
type: 'PAGE_SHOW',
|
|
242
|
+
url: window.location.href,
|
|
243
|
+
timestamp: Date.now(),
|
|
244
|
+
persisted: event.persisted // 是否从 bfcache 恢复
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// 如果是从 bfcache 恢复,重置路由计时器
|
|
248
|
+
if (event.persisted) {
|
|
249
|
+
routeStartTime = Date.now();
|
|
250
|
+
}
|
|
251
|
+
} catch (error) {
|
|
252
|
+
logger.warn('Failed to add PAGE_SHOW event (recording may have stopped)', error);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* 处理页面可见性变化事件(移动端切换应用/标签页)
|
|
258
|
+
*/
|
|
259
|
+
function handleVisibilityChange() {
|
|
260
|
+
try {
|
|
261
|
+
var isHidden = document.visibilityState === 'hidden';
|
|
262
|
+
record.addCustomEvent(EVENT_PAGE_LIFECYCLE, {
|
|
263
|
+
type: isHidden ? 'PAGE_VISIBILITY_HIDDEN' : 'PAGE_VISIBILITY_VISIBLE',
|
|
264
|
+
url: window.location.href,
|
|
265
|
+
timestamp: Date.now()
|
|
266
|
+
});
|
|
267
|
+
} catch (error) {
|
|
268
|
+
logger.warn('Failed to add visibility change event (recording may have stopped)', error);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
197
272
|
/**
|
|
198
273
|
* 初始化路由监控
|
|
199
274
|
*/
|
|
200
275
|
export function initRouterMonitor(config) {
|
|
201
|
-
var _defaultConfig$enable2, _defaultConfig$trackH3, _defaultConfig$trackH4, _defaultConfig$trackP2, _defaultConfig$ignore2
|
|
276
|
+
var _defaultConfig$enable2, _defaultConfig$trackH3, _defaultConfig$trackH4, _defaultConfig$trackP2, _defaultConfig$ignore2;
|
|
202
277
|
if (isInitialized || typeof window === 'undefined') return;
|
|
203
278
|
|
|
204
279
|
// 合并配置
|
|
@@ -208,16 +283,13 @@ export function initRouterMonitor(config) {
|
|
|
208
283
|
trackHashChange: (_defaultConfig$trackH3 = defaultConfig.trackHashChange) !== null && _defaultConfig$trackH3 !== void 0 ? _defaultConfig$trackH3 : true,
|
|
209
284
|
trackHistoryChange: (_defaultConfig$trackH4 = defaultConfig.trackHistoryChange) !== null && _defaultConfig$trackH4 !== void 0 ? _defaultConfig$trackH4 : true,
|
|
210
285
|
trackPageStayTime: (_defaultConfig$trackP2 = defaultConfig.trackPageStayTime) !== null && _defaultConfig$trackP2 !== void 0 ? _defaultConfig$trackP2 : true,
|
|
211
|
-
ignoreRoutes: (_defaultConfig$ignore2 = defaultConfig.ignoreRoutes) !== null && _defaultConfig$ignore2 !== void 0 ? _defaultConfig$ignore2 : []
|
|
212
|
-
customMatchers: (_defaultConfig$custom2 = defaultConfig.customMatchers) !== null && _defaultConfig$custom2 !== void 0 ? _defaultConfig$custom2 : []
|
|
286
|
+
ignoreRoutes: (_defaultConfig$ignore2 = defaultConfig.ignoreRoutes) !== null && _defaultConfig$ignore2 !== void 0 ? _defaultConfig$ignore2 : []
|
|
213
287
|
}, config || {});
|
|
214
288
|
|
|
215
289
|
// 如果未启用,直接返回
|
|
216
290
|
if (!routerConfig.enable) {
|
|
217
|
-
console.log('RLog route monitor is disabled by config');
|
|
218
291
|
return;
|
|
219
292
|
}
|
|
220
|
-
console.log('RLog route monitor initialized with config:', routerConfig);
|
|
221
293
|
|
|
222
294
|
// 设置初始路由
|
|
223
295
|
currentRoute = getCurrentRoute();
|
|
@@ -230,6 +302,16 @@ export function initRouterMonitor(config) {
|
|
|
230
302
|
if (routerConfig.trackHashChange) {
|
|
231
303
|
window.addEventListener('hashchange', handleHashChange);
|
|
232
304
|
}
|
|
305
|
+
|
|
306
|
+
// 监听页面生命周期事件
|
|
307
|
+
window.addEventListener('load', handlePageLoad);
|
|
308
|
+
window.addEventListener('beforeunload', handlePageUnload);
|
|
309
|
+
|
|
310
|
+
// 监听移动端页面生命周期事件
|
|
311
|
+
// pagehide/pageshow 在移动端比 beforeunload 更可靠
|
|
312
|
+
window.addEventListener('pagehide', handlePageHide);
|
|
313
|
+
window.addEventListener('pageshow', handlePageShow);
|
|
314
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
233
315
|
isInitialized = true;
|
|
234
316
|
}
|
|
235
317
|
|
|
@@ -268,11 +350,15 @@ export function stopRouterMonitor() {
|
|
|
268
350
|
if (typeof window !== 'undefined') {
|
|
269
351
|
window.removeEventListener('popstate', handlePopState);
|
|
270
352
|
window.removeEventListener('hashchange', handleHashChange);
|
|
353
|
+
window.removeEventListener('load', handlePageLoad);
|
|
354
|
+
window.removeEventListener('beforeunload', handlePageUnload);
|
|
355
|
+
window.removeEventListener('pagehide', handlePageHide);
|
|
356
|
+
window.removeEventListener('pageshow', handlePageShow);
|
|
357
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
271
358
|
}
|
|
272
359
|
|
|
273
360
|
// 重置状态
|
|
274
361
|
isInitialized = false;
|
|
275
362
|
originalPushState = null;
|
|
276
363
|
originalReplaceState = null;
|
|
277
|
-
console.log('RLog router monitor stopped');
|
|
278
364
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rrweb.d.ts","sourceRoot":"","sources":["../../../src/lib/rrweb.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rrweb.d.ts","sourceRoot":"","sources":["../../../src/lib/rrweb.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,UAAU,YAKtB,CAAC;AAEF,eAAO,MAAM,WAAW,YA+FvB,CAAC"}
|
package/dist/esm/lib/rrweb.js
CHANGED
|
@@ -4,12 +4,14 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
4
4
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
5
5
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
6
6
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
-
import
|
|
7
|
+
import { record } from 'rrweb';
|
|
8
8
|
import { getRecordConsolePlugin } from '@rrweb/rrweb-plugin-console-record';
|
|
9
|
-
import { getDeviceId } from "./utils";
|
|
9
|
+
import { getDeviceId, getStorageKey, isIOS } from "./utils";
|
|
10
10
|
import { storage } from "./storage-manager";
|
|
11
11
|
import { setCustomHeaders, setWhiteListUrls, watchXhr } from "./net";
|
|
12
12
|
import { getConfig } from "./config";
|
|
13
|
+
import logger from "./logger";
|
|
14
|
+
import { STORAGE_KEY_DEVICE_ID, DEFAULT_WHITE_LIST_URLS, CANVAS_EXPORT_TYPE_WEBP, CANVAS_EXPORT_TYPE_JPEG, CANVAS_EXPORT_QUALITY } from "./constants";
|
|
13
15
|
var stopRecordFn = null;
|
|
14
16
|
export var stopRecord = function stopRecord() {
|
|
15
17
|
if (stopRecordFn) {
|
|
@@ -18,20 +20,21 @@ export var stopRecord = function stopRecord() {
|
|
|
18
20
|
}
|
|
19
21
|
};
|
|
20
22
|
export var startRecord = function startRecord() {
|
|
23
|
+
var _config$ignoreCSSAttr;
|
|
21
24
|
// 检查采集总开关
|
|
22
25
|
var config = getConfig();
|
|
23
26
|
if (!config.enable) {
|
|
24
|
-
console.log('RLog recording is disabled by config');
|
|
25
27
|
return;
|
|
26
28
|
}
|
|
27
29
|
var deviceId = getDeviceId();
|
|
30
|
+
var storageKey = getStorageKey();
|
|
28
31
|
|
|
29
32
|
// 根据配置决定是否清空存储数据
|
|
30
33
|
if (config.clearStorageBeforeRecord) {
|
|
31
|
-
storage.clear(
|
|
32
|
-
|
|
34
|
+
storage.clear(storageKey).then(function () {
|
|
35
|
+
// cleared
|
|
33
36
|
}).catch(function (error) {
|
|
34
|
-
|
|
37
|
+
logger.warn('Failed to clear storage before recording', error);
|
|
35
38
|
});
|
|
36
39
|
}
|
|
37
40
|
var plugins = [];
|
|
@@ -51,49 +54,57 @@ export var startRecord = function startRecord() {
|
|
|
51
54
|
})
|
|
52
55
|
});
|
|
53
56
|
plugins.push(getRecordConsolePlugin(consoleConfig));
|
|
54
|
-
} else {
|
|
55
|
-
console.log('RLog console recording is disabled by config');
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
+
|
|
59
|
+
// 构建 ignoreCSSAttributes 集合
|
|
60
|
+
var ignoreCSSAttributes = (_config$ignoreCSSAttr = config.ignoreCSSAttributes) !== null && _config$ignoreCSSAttr !== void 0 && _config$ignoreCSSAttr.length ? new Set(config.ignoreCSSAttributes) : new Set();
|
|
61
|
+
stopRecordFn = record({
|
|
58
62
|
emit: function emit(event) {
|
|
59
63
|
// you should use console.log in this way to avoid errors.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
// const defaultLog = (console.log as any)['__rrweb_original__']
|
|
65
|
+
// ? (console.log as any)['__rrweb_original__']
|
|
66
|
+
// : console.log;
|
|
67
|
+
// if (event.type !== rrweb.EventType.IncrementalSnapshot) {
|
|
68
|
+
// // 过滤不打印出增量更新的日志
|
|
69
|
+
// defaultLog('event', event);
|
|
70
|
+
// }
|
|
71
|
+
|
|
72
|
+
// 统一写入 Storage(full 和 error 模式共用)
|
|
73
|
+
try {
|
|
74
|
+
storage.push(storageKey, event);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
// 存储失败不应影响 rrweb 录制
|
|
77
|
+
logger.warn('Failed to storage push event:', error);
|
|
64
78
|
}
|
|
65
|
-
storage.push(deviceId, event);
|
|
66
79
|
},
|
|
67
80
|
recordCanvas: true,
|
|
68
|
-
sampling:
|
|
69
|
-
canvas: config.samplingRate
|
|
70
|
-
}, config.sampling || {}),
|
|
81
|
+
sampling: config.sampling,
|
|
71
82
|
checkoutEveryNms: config.checkoutEveryNms,
|
|
72
83
|
ignoreClass: config.ignoreClass,
|
|
73
84
|
blockClass: config.blockClass,
|
|
74
85
|
maskTextClass: config.maskTextClass,
|
|
75
|
-
//
|
|
86
|
+
// 忽略高频 CSS 属性变更,避免动画 CSS 变量产生冗余增量快照
|
|
87
|
+
ignoreCSSAttributes: ignoreCSSAttributes,
|
|
88
|
+
// 图像的格式:iOS Safari 不支持 canvas 导出 webp(会静默回退为 png 无损,体积大),降级为 jpeg
|
|
76
89
|
dataURLOptions: {
|
|
77
|
-
type:
|
|
78
|
-
quality:
|
|
90
|
+
type: isIOS() ? CANVAS_EXPORT_TYPE_JPEG : CANVAS_EXPORT_TYPE_WEBP,
|
|
91
|
+
quality: CANVAS_EXPORT_QUALITY
|
|
79
92
|
},
|
|
80
93
|
collectFonts: true,
|
|
81
94
|
recordCrossOriginIframes: true,
|
|
82
|
-
plugins: [].concat(plugins)
|
|
83
|
-
// 是否使用rrweb的packFn压缩事件数据,默认false
|
|
84
|
-
packFn: config.packEvents ? rrweb.pack : undefined
|
|
95
|
+
plugins: [].concat(plugins)
|
|
85
96
|
});
|
|
86
97
|
|
|
87
98
|
// 设置网络监控
|
|
88
|
-
setCustomHeaders({
|
|
89
|
-
|
|
90
|
-
});
|
|
91
|
-
setWhiteListUrls(['http://alipay-rmsdeploy-image.cn-hangzhou.alipay.aliyun-inc.com']);
|
|
99
|
+
setCustomHeaders(_defineProperty({}, STORAGE_KEY_DEVICE_ID, deviceId));
|
|
100
|
+
setWhiteListUrls(DEFAULT_WHITE_LIST_URLS);
|
|
92
101
|
|
|
93
102
|
// 根据配置决定是否开启接口请求抓取
|
|
94
103
|
if (config.http) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
try {
|
|
105
|
+
watchXhr(record);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
logger.warn('Failed to initialize HTTP monitoring:', error);
|
|
108
|
+
}
|
|
98
109
|
}
|
|
99
110
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 上报接口加签模块
|
|
3
|
+
*
|
|
4
|
+
* 签名算法:
|
|
5
|
+
* 1. md5 = MD5(rrweb 录制的 JSON 数据)
|
|
6
|
+
* 2. ts = Date.now()
|
|
7
|
+
* 3. secret = MD5(md5 + ts) — 一次性签名密钥
|
|
8
|
+
* 4. sign = HMAC-SHA256(encodeURIComponent(sortedParams) + md5 + ts, secret)
|
|
9
|
+
*
|
|
10
|
+
* 请求头:
|
|
11
|
+
* x-bk-sign = sign
|
|
12
|
+
* x-bk-ts = ts
|
|
13
|
+
* x-bk-dm = md5
|
|
14
|
+
*/
|
|
15
|
+
export declare function md5(str: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* 将查询参数按 key 字母序排列并拼接为字符串,过滤空值
|
|
18
|
+
* @param params 查询参数键值对
|
|
19
|
+
* @returns 排序后的参数字符串,如 "appId=xxx&deviceId=yyy&startTime=zzz"
|
|
20
|
+
*/
|
|
21
|
+
export declare function sortAndConcatParams(params: Record<string, string>): string;
|
|
22
|
+
/**
|
|
23
|
+
* 计算上报接口的签名请求头
|
|
24
|
+
*
|
|
25
|
+
* 签名流程:
|
|
26
|
+
* 1. md5 = MD5(上报数据的 JSON 字符串)
|
|
27
|
+
* 2. ts = 当前时间戳(毫秒)
|
|
28
|
+
* 3. secret = MD5(md5 + ts) — 一次性签名密钥
|
|
29
|
+
* 4. sign = HMAC-SHA256(encodeURIComponent(sortedParams) + md5 + ts, secret)
|
|
30
|
+
*
|
|
31
|
+
* @param queryParams 查询参数键值对
|
|
32
|
+
* @param jsonData 上报数据的 JSON 字符串
|
|
33
|
+
* @returns 签名请求头 { x-bk-sign, x-bk-ts, x-bk-dm }
|
|
34
|
+
*/
|
|
35
|
+
export declare function computeSignHeaders(queryParams: Record<string, string>, jsonData: string): Promise<Record<string, string>>;
|
|
36
|
+
//# sourceMappingURL=sign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../../src/lib/sign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAqKH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvC;AAoMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAW1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAajC"}
|