@antglobal/rlog-sdk 0.0.1755855517-dev.11 → 0.0.1755855517-dev.13

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 (50) hide show
  1. package/dist/esm/lib/api.d.ts +10 -0
  2. package/dist/esm/lib/api.d.ts.map +1 -1
  3. package/dist/esm/lib/api.js +47 -31
  4. package/dist/esm/lib/config.d.ts +1 -0
  5. package/dist/esm/lib/config.d.ts.map +1 -1
  6. package/dist/esm/lib/config.js +2 -0
  7. package/dist/esm/lib/error.d.ts.map +1 -1
  8. package/dist/esm/lib/error.js +65 -138
  9. package/dist/esm/lib/init.d.ts.map +1 -1
  10. package/dist/esm/lib/init.js +14 -7
  11. package/dist/esm/lib/net.d.ts +1 -0
  12. package/dist/esm/lib/net.d.ts.map +1 -1
  13. package/dist/esm/lib/net.js +33 -2
  14. package/dist/esm/lib/router-monitor.d.ts.map +1 -1
  15. package/dist/esm/lib/router-monitor.js +100 -0
  16. package/dist/esm/lib/upload-worker-manager.d.ts +37 -0
  17. package/dist/esm/lib/upload-worker-manager.d.ts.map +1 -0
  18. package/dist/esm/lib/upload-worker-manager.js +482 -0
  19. package/dist/esm/lib/upload-worker.d.ts +59 -0
  20. package/dist/esm/lib/upload-worker.d.ts.map +1 -0
  21. package/dist/esm/lib/upload-worker.js +26 -0
  22. package/dist/esm/lib/uploader.d.ts +5 -0
  23. package/dist/esm/lib/uploader.d.ts.map +1 -1
  24. package/dist/esm/lib/uploader.js +58 -10
  25. package/dist/lib/lib/api.d.ts +10 -0
  26. package/dist/lib/lib/api.d.ts.map +1 -1
  27. package/dist/lib/lib/api.js +48 -31
  28. package/dist/lib/lib/config.d.ts +1 -0
  29. package/dist/lib/lib/config.d.ts.map +1 -1
  30. package/dist/lib/lib/config.js +2 -0
  31. package/dist/lib/lib/error.d.ts.map +1 -1
  32. package/dist/lib/lib/error.js +65 -138
  33. package/dist/lib/lib/init.d.ts.map +1 -1
  34. package/dist/lib/lib/init.js +13 -6
  35. package/dist/lib/lib/net.d.ts +1 -0
  36. package/dist/lib/lib/net.d.ts.map +1 -1
  37. package/dist/lib/lib/net.js +33 -1
  38. package/dist/lib/lib/router-monitor.d.ts.map +1 -1
  39. package/dist/lib/lib/router-monitor.js +100 -0
  40. package/dist/lib/lib/upload-worker-manager.d.ts +37 -0
  41. package/dist/lib/lib/upload-worker-manager.d.ts.map +1 -0
  42. package/dist/lib/lib/upload-worker-manager.js +491 -0
  43. package/dist/lib/lib/upload-worker.d.ts +59 -0
  44. package/dist/lib/lib/upload-worker.d.ts.map +1 -0
  45. package/dist/lib/lib/upload-worker.js +32 -0
  46. package/dist/lib/lib/uploader.d.ts +5 -0
  47. package/dist/lib/lib/uploader.d.ts.map +1 -1
  48. package/dist/lib/lib/uploader.js +58 -10
  49. package/dist/rlog-sdk.min.js +1 -1
  50. package/package.json +3 -2
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Upload Worker 脚本
3
+ *
4
+ * 在 Web Worker 中执行上传任务,将 JSON 序列化 + FormData 构建 + XHR 上传
5
+ * 从主线程移到 Worker 线程,避免阻塞 UI。
6
+ *
7
+ * 通信协议:
8
+ * 主线程 → Worker: WorkerCommand
9
+ * Worker → 主线程: WorkerMessage
10
+ */
11
+ export interface WorkerConfig {
12
+ serv: string;
13
+ appId: string;
14
+ deviceId: string;
15
+ uploadInterval: number;
16
+ maxRetryCount: number;
17
+ }
18
+ export type WorkerCommand = {
19
+ type: 'START';
20
+ config: WorkerConfig;
21
+ } | {
22
+ type: 'STOP';
23
+ } | {
24
+ type: 'UPLOAD_BATCH';
25
+ batchId: string;
26
+ events: any[];
27
+ queryParams: Record<string, string>;
28
+ customHeaders: Record<string, string>;
29
+ } | {
30
+ type: 'UPDATE_CONFIG';
31
+ config: Partial<WorkerConfig>;
32
+ } | {
33
+ type: 'SET_ERROR_MODE_UPLOADING';
34
+ uploading: boolean;
35
+ };
36
+ export type WorkerMessage = {
37
+ type: 'READY';
38
+ } | {
39
+ type: 'REQUEST_BATCH';
40
+ mode: 'full' | 'error';
41
+ } | {
42
+ type: 'UPLOAD_SUCCESS';
43
+ batchId: string;
44
+ } | {
45
+ type: 'UPLOAD_FAILURE';
46
+ batchId: string;
47
+ error: string;
48
+ failureCount: number;
49
+ } | {
50
+ type: 'MAX_RETRY_REACHED';
51
+ batchId: string;
52
+ error: string;
53
+ };
54
+ /**
55
+ * 返回 Worker 脚本的源代码字符串
56
+ * 用于通过 Blob URL 内联创建 Worker
57
+ */
58
+ export declare function getUploadWorkerCode(): string;
59
+ //# sourceMappingURL=upload-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-worker.d.ts","sourceRoot":"","sources":["../../../src/lib/upload-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAGD,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACpI;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,0BAA0B,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAG7D,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAIlE;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAsN5C"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Upload Worker 脚本
3
+ *
4
+ * 在 Web Worker 中执行上传任务,将 JSON 序列化 + FormData 构建 + XHR 上传
5
+ * 从主线程移到 Worker 线程,避免阻塞 UI。
6
+ *
7
+ * 通信协议:
8
+ * 主线程 → Worker: WorkerCommand
9
+ * Worker → 主线程: WorkerMessage
10
+ */
11
+
12
+ // ==================== 类型定义 ====================
13
+
14
+ // 主线程 → Worker
15
+
16
+ // Worker → 主线程
17
+
18
+ // ==================== Worker 代码(字符串形式) ====================
19
+
20
+ /**
21
+ * 返回 Worker 脚本的源代码字符串
22
+ * 用于通过 Blob URL 内联创建 Worker
23
+ */
24
+ export function getUploadWorkerCode() {
25
+ return "\n'use strict';\n\n// ===== Worker \u5185\u90E8\u72B6\u6001 =====\nvar config = null;\nvar pollTimer = null;\nvar isRunning = false;\nvar errorModeUploading = false;\nvar failureCountMap = {};\n\n// ===== UUID \u751F\u6210 =====\nfunction generateUUID() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = (Math.random() * 16) | 0;\n var v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n// ===== \u6784\u5EFA\u4E0A\u4F20 URL =====\nfunction buildUploadUrl(serv, queryParams) {\n var params = [];\n for (var key in queryParams) {\n if (queryParams.hasOwnProperty(key) && queryParams[key] != null && queryParams[key] !== '') {\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(queryParams[key]));\n }\n }\n var queryString = params.join('&');\n return serv + (queryString ? '?' + queryString : '');\n}\n\n// ===== \u6267\u884C\u4E0A\u4F20 =====\nfunction performUpload(msg) {\n var batchId = msg.batchId;\n var events = msg.events;\n var queryParams = msg.queryParams;\n var customHeaders = msg.customHeaders;\n\n try {\n // JSON \u5E8F\u5217\u5316\u5728 Worker \u4E2D\u6267\u884C\uFF0C\u4E0D\u963B\u585E\u4E3B\u7EBF\u7A0B\n var jsonStr = JSON.stringify(events);\n var blob = new Blob([jsonStr], { type: 'application/json' });\n var formData = new FormData();\n formData.append('file', blob, generateUUID() + '.json');\n\n var url = buildUploadUrl(config ? config.serv : '', queryParams);\n\n var xhr = new XMLHttpRequest();\n xhr.open('POST', url, true);\n xhr.timeout = 10000;\n\n // \u8BBE\u7F6E\u81EA\u5B9A\u4E49\u8BF7\u6C42\u5934\n if (customHeaders) {\n for (var key in customHeaders) {\n if (customHeaders.hasOwnProperty(key)) {\n xhr.setRequestHeader(key, customHeaders[key]);\n }\n }\n }\n\n xhr.onreadystatechange = function() {\n if (xhr.readyState === 4) {\n if (xhr.status >= 200 && xhr.status < 300) {\n // \u68C0\u67E5\u4E1A\u52A1\u5C42 success \u5B57\u6BB5\n var uploadSuccess = true;\n var errorMessage = '';\n try {\n var responseData = JSON.parse(xhr.responseText);\n if (responseData && typeof responseData === 'object' && responseData.success === false) {\n uploadSuccess = false;\n errorMessage = responseData.errorMessage || 'Upload failed with success=false';\n }\n } catch(e) {\n // \u65E0\u6CD5\u89E3\u6790 JSON\uFF0C\u89C6\u4E3A\u6210\u529F\n }\n\n if (uploadSuccess) {\n // \u4E0A\u4F20\u6210\u529F\uFF0C\u91CD\u7F6E\u5931\u8D25\u8BA1\u6570\n var batchKey = config ? (config.appId + '_' + config.deviceId) : batchId;\n delete failureCountMap[batchKey];\n self.postMessage({ type: 'UPLOAD_SUCCESS', batchId: batchId });\n } else {\n handleFailure(batchId, errorMessage);\n }\n } else {\n handleFailure(batchId, 'HTTP ' + xhr.status + ': ' + xhr.statusText);\n }\n }\n };\n\n xhr.onerror = function() {\n handleFailure(batchId, 'Network error');\n };\n\n xhr.ontimeout = function() {\n handleFailure(batchId, 'Request timeout');\n };\n\n xhr.send(formData);\n } catch (e) {\n handleFailure(batchId, 'Upload exception: ' + (e.message || String(e)));\n }\n}\n\n// ===== \u5904\u7406\u4E0A\u4F20\u5931\u8D25 =====\nfunction handleFailure(batchId, errorMessage) {\n var batchKey = config ? (config.appId + '_' + config.deviceId) : batchId;\n var currentCount = failureCountMap[batchKey] || 0;\n var newCount = currentCount + 1;\n failureCountMap[batchKey] = newCount;\n\n var maxRetry = (config && config.maxRetryCount) ? config.maxRetryCount : 3;\n\n if (newCount >= maxRetry) {\n // \u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570\n delete failureCountMap[batchKey];\n self.postMessage({\n type: 'MAX_RETRY_REACHED',\n batchId: batchId,\n error: errorMessage\n });\n } else {\n self.postMessage({\n type: 'UPLOAD_FAILURE',\n batchId: batchId,\n error: errorMessage,\n failureCount: newCount\n });\n }\n}\n\n// ===== \u8F6E\u8BE2\u8C03\u5EA6 =====\nfunction startPolling() {\n if (pollTimer) {\n clearInterval(pollTimer);\n }\n\n var interval = (config && config.uploadInterval) ? config.uploadInterval : 2000;\n\n pollTimer = setInterval(function() {\n if (!isRunning) return;\n\n // \u5411\u4E3B\u7EBF\u7A0B\u8BF7\u6C42\u6570\u636E\u6279\u6B21\n // \u4E3B\u7EBF\u7A0B\u4F1A\u6839\u636E\u5F53\u524D\u6A21\u5F0F\uFF08full/error\uFF09\u548C\u72B6\u6001\u51B3\u5B9A\u662F\u5426\u63D0\u4F9B\u6570\u636E\n self.postMessage({\n type: 'REQUEST_BATCH',\n mode: errorModeUploading ? 'error' : 'full'\n });\n }, interval);\n}\n\nfunction stopPolling() {\n if (pollTimer) {\n clearInterval(pollTimer);\n pollTimer = null;\n }\n}\n\n// ===== \u6E05\u7406 =====\nfunction cleanup() {\n isRunning = false;\n stopPolling();\n failureCountMap = {};\n config = null;\n errorModeUploading = false;\n}\n\n// ===== \u6D88\u606F\u5904\u7406 =====\nself.onmessage = function(e) {\n var msg = e.data;\n if (!msg || !msg.type) return;\n\n switch (msg.type) {\n case 'START':\n config = msg.config;\n isRunning = true;\n failureCountMap = {};\n startPolling();\n break;\n\n case 'STOP':\n cleanup();\n break;\n\n case 'UPLOAD_BATCH':\n if (isRunning) {\n performUpload(msg);\n }\n break;\n\n case 'UPDATE_CONFIG':\n if (msg.config) {\n for (var key in msg.config) {\n if (msg.config.hasOwnProperty(key) && config) {\n config[key] = msg.config[key];\n }\n }\n // \u5982\u679C uploadInterval \u53D8\u4E86\uFF0C\u91CD\u542F\u8F6E\u8BE2\n if (msg.config.uploadInterval && isRunning) {\n startPolling();\n }\n }\n break;\n\n case 'SET_ERROR_MODE_UPLOADING':\n errorModeUploading = msg.uploading;\n break;\n }\n};\n\n// Worker \u5C31\u7EEA\u901A\u77E5\nself.postMessage({ type: 'READY' });\n";
26
+ }
@@ -1,15 +1,19 @@
1
1
  /**
2
2
  * 设置错误模式上传状态
3
3
  * 由 ErrorTrigger 调用:错误触发时设置为 true,cooldown 结束时设置为 false
4
+ * 自动分发到 Worker 模式或主线程模式
4
5
  */
5
6
  export declare function setErrorModeUploading(uploading: boolean): void;
6
7
  /**
7
8
  * 设置错误模式上传时间窗口起点
8
9
  * 由 ErrorTrigger 调用,记录错误触发前的时间窗口起点
10
+ * 自动分发到 Worker 模式或主线程模式
9
11
  */
10
12
  export declare function setErrorModeWindowStart(startTime: number): void;
11
13
  /**
12
14
  * 启动数据上传循环
15
+ * 优先尝试 Worker 模式,失败则降级到主线程模式
16
+ *
13
17
  * 全量模式:持续轮询上传
14
18
  * 错误模式:idle 时跳过上传,uploading 时轮询上传(由 ErrorTrigger 控制状态)
15
19
  * @param serv 服务器地址
@@ -18,6 +22,7 @@ export declare function setErrorModeWindowStart(startTime: number): void;
18
22
  export declare function startUploadLoop(serv: string, appId: string): void;
19
23
  /**
20
24
  * 取消上传循环
25
+ * 同时处理 Worker 模式和主线程模式
21
26
  */
22
27
  export declare function cancelUploadLoop(): void;
23
28
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../../src/lib/uploader.ts"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAE9D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE/D;AAyGD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAmIjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAMtC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
1
+ {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../../src/lib/uploader.ts"],"names":[],"mappings":"AAgCA;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAM/D;AAqPD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAYjE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAWvC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAYtC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
@@ -8,8 +8,11 @@ import { getDeviceId } from "./utils";
8
8
  import { getConfig } from "./config";
9
9
  import { record } from 'rrweb';
10
10
  import { cancelRlog } from "./init";
11
+ import { initWorkerUpload, destroyWorker, isUsingWorkerMode, setWorkerErrorModeUploading, setWorkerErrorModeWindowStart } from "./upload-worker-manager";
11
12
  import logger from "./logger";
12
13
 
14
+ // ==================== 主线程降级模式状态 ====================
15
+
13
16
  // 全局取消标志
14
17
  var isUploadCancelled = false;
15
18
 
@@ -28,21 +31,33 @@ var errorModeWindowStart = 0;
28
31
  /**
29
32
  * 设置错误模式上传状态
30
33
  * 由 ErrorTrigger 调用:错误触发时设置为 true,cooldown 结束时设置为 false
34
+ * 自动分发到 Worker 模式或主线程模式
31
35
  */
32
36
  export function setErrorModeUploading(uploading) {
33
- errorModeUploading = uploading;
37
+ if (isUsingWorkerMode()) {
38
+ setWorkerErrorModeUploading(uploading);
39
+ } else {
40
+ errorModeUploading = uploading;
41
+ }
34
42
  }
35
43
 
36
44
  /**
37
45
  * 设置错误模式上传时间窗口起点
38
46
  * 由 ErrorTrigger 调用,记录错误触发前的时间窗口起点
47
+ * 自动分发到 Worker 模式或主线程模式
39
48
  */
40
49
  export function setErrorModeWindowStart(startTime) {
41
- errorModeWindowStart = startTime;
50
+ if (isUsingWorkerMode()) {
51
+ setWorkerErrorModeWindowStart(startTime);
52
+ } else {
53
+ errorModeWindowStart = startTime;
54
+ }
42
55
  }
43
56
 
57
+ // ==================== 主线程降级模式上传逻辑 ====================
58
+
44
59
  /**
45
- * 统一的上传函数
60
+ * 统一的上传函数(主线程降级模式)
46
61
  * @param serv 服务器地址
47
62
  * @param appId 应用ID
48
63
  * @param events 要上传的事件数组
@@ -52,7 +67,7 @@ function uploadEvents(_x, _x2, _x3) {
52
67
  return _uploadEvents.apply(this, arguments);
53
68
  }
54
69
  /**
55
- * 处理上传失败
70
+ * 处理上传失败(主线程降级模式)
56
71
  * @param events 失败的事件
57
72
  * @param error 错误信息
58
73
  * @param appId 应用ID
@@ -106,11 +121,7 @@ function handleUploadFailure(_x4, _x5, _x6, _x7, _x8, _x9) {
106
121
  return _handleUploadFailure.apply(this, arguments);
107
122
  }
108
123
  /**
109
- * 启动数据上传循环
110
- * 全量模式:持续轮询上传
111
- * 错误模式:idle 时跳过上传,uploading 时轮询上传(由 ErrorTrigger 控制状态)
112
- * @param serv 服务器地址
113
- * @param appId 应用ID
124
+ * 主线程降级模式的上传循环
114
125
  */
115
126
  function _handleUploadFailure() {
116
127
  _handleUploadFailure = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(events, error, appId, serv, maxRetryCount, currentCount) {
@@ -183,7 +194,7 @@ function _handleUploadFailure() {
183
194
  }));
184
195
  return _handleUploadFailure.apply(this, arguments);
185
196
  }
186
- export function startUploadLoop(serv, appId) {
197
+ function startMainThreadUploadLoop(serv, appId) {
187
198
  var push = /*#__PURE__*/function () {
188
199
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
189
200
  var currentConfig, isErrorMode, events, windowStart, config, consumeOnly, result, batchKey, lastEvent, maxRetryCount, _batchKey, currentCount, shouldStop;
@@ -346,10 +357,41 @@ export function startUploadLoop(serv, appId) {
346
357
  push();
347
358
  }
348
359
 
360
+ // ==================== 对外 API ====================
361
+
362
+ /**
363
+ * 启动数据上传循环
364
+ * 优先尝试 Worker 模式,失败则降级到主线程模式
365
+ *
366
+ * 全量模式:持续轮询上传
367
+ * 错误模式:idle 时跳过上传,uploading 时轮询上传(由 ErrorTrigger 控制状态)
368
+ * @param serv 服务器地址
369
+ * @param appId 应用ID
370
+ */
371
+ export function startUploadLoop(serv, appId) {
372
+ // 优先尝试 Worker 模式
373
+ var workerInitialized = initWorkerUpload(serv, appId);
374
+ if (workerInitialized) {
375
+ logger.log('Upload loop started in Worker mode');
376
+ return;
377
+ }
378
+
379
+ // Worker 不可用,降级到主线程模式
380
+ logger.log('Worker not available, falling back to main thread upload');
381
+ startMainThreadUploadLoop(serv, appId);
382
+ }
383
+
349
384
  /**
350
385
  * 取消上传循环
386
+ * 同时处理 Worker 模式和主线程模式
351
387
  */
352
388
  export function cancelUploadLoop() {
389
+ // 销毁 Worker(如果存在)
390
+ if (isUsingWorkerMode()) {
391
+ destroyWorker();
392
+ }
393
+
394
+ // 重置主线程模式状态
353
395
  isUploadCancelled = true;
354
396
  isUploading = false;
355
397
  errorModeUploading = false;
@@ -360,6 +402,12 @@ export function cancelUploadLoop() {
360
402
  * 重置上传循环状态(用于重新初始化)
361
403
  */
362
404
  export function resetUploadLoop() {
405
+ // 销毁 Worker(如果存在)
406
+ if (isUsingWorkerMode()) {
407
+ destroyWorker();
408
+ }
409
+
410
+ // 重置主线程模式状态
363
411
  isUploadCancelled = false;
364
412
  isUploading = false;
365
413
  errorModeUploading = false;
@@ -4,6 +4,16 @@ type UploadOptions = {
4
4
  deviceId: string;
5
5
  appId: string;
6
6
  };
7
+ /**
8
+ * 构建上传查询参数(纯函数,供 Worker 管理器复用)
9
+ * @param opts 包含 appId、deviceId、data 的选项
10
+ * @returns 查询参数键值对
11
+ */
12
+ export declare function buildQueryParams(opts: {
13
+ appId: string;
14
+ deviceId: string;
15
+ data: any[];
16
+ }): Record<string, string>;
7
17
  export declare const upload: (opt: UploadOptions) => Promise<void>;
8
18
  export {};
9
19
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/lib/api.ts"],"names":[],"mappings":"AAKA,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAqBF,eAAO,MAAM,MAAM,QAAe,aAAa,kBAuD9C,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/lib/api.ts"],"names":[],"mappings":"AAKA,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAqBF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,GAAG,EAAE,CAAC;CACb,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyBzB;AAED,eAAO,MAAM,MAAM,QAAe,aAAa,kBAsC9C,CAAC"}
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.buildQueryParams = buildQueryParams;
6
7
  exports.upload = void 0;
7
8
  var _utils = require("./utils");
8
9
  var _request = require("./request");
@@ -29,32 +30,48 @@ var cacheUrlParams = function cacheUrlParams() {
29
30
  var getCachedParam = function getCachedParam(paramName) {
30
31
  return sessionStorage.getItem("rlog-".concat(paramName));
31
32
  };
33
+
34
+ /**
35
+ * 构建上传查询参数(纯函数,供 Worker 管理器复用)
36
+ * @param opts 包含 appId、deviceId、data 的选项
37
+ * @returns 查询参数键值对
38
+ */
39
+ function buildQueryParams(opts) {
40
+ var _opts$data, _opts$data2;
41
+ // 缓存URL中的参数
42
+ cacheUrlParams();
43
+ var lastIndex = opts.data && opts.data.length > 0 ? opts.data.length - 1 : -1;
44
+ var queryParams = {
45
+ deviceId: opts.deviceId,
46
+ appId: opts.appId,
47
+ startTime: (_opts$data = opts.data) === null || _opts$data === void 0 || (_opts$data = _opts$data[0]) === null || _opts$data === void 0 ? void 0 : _opts$data.timestamp,
48
+ endTime: (_opts$data2 = opts.data) === null || _opts$data2 === void 0 || (_opts$data2 = _opts$data2[lastIndex]) === null || _opts$data2 === void 0 ? void 0 : _opts$data2.timestamp
49
+ };
50
+
51
+ // 从配置中获取需要上报的参数名称列表
52
+ var config = (0, _config.getConfig)();
53
+ var paramsToReport = config.urlParamsToCache || ['taskId']; // 默认上报taskId
54
+
55
+ // 添加缓存的参数到查询字符串中
56
+ paramsToReport.forEach(function (paramName) {
57
+ var paramValue = getCachedParam(paramName);
58
+ if (paramValue) {
59
+ queryParams[paramName] = paramValue;
60
+ }
61
+ });
62
+ return queryParams;
63
+ }
32
64
  var upload = exports.upload = /*#__PURE__*/function () {
33
65
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(opt) {
34
- var _opt$data, _opt$data2;
35
- var lastIndex, queryParams, config, paramsToReport, queryString, api, formData, customHeaders, response, responseData, error;
66
+ var queryParams, queryString, api, formData, customHeaders, response, responseData, error;
36
67
  return _regeneratorRuntime().wrap(function _callee$(_context) {
37
68
  while (1) switch (_context.prev = _context.next) {
38
69
  case 0:
39
- // 缓存URL中的参数
40
- cacheUrlParams();
41
-
42
- // 构建查询字符串
43
- lastIndex = opt.data && opt.data.length > 0 ? opt.data.length - 1 : -1;
44
- queryParams = {
45
- deviceId: opt.deviceId,
70
+ // 构建查询参数
71
+ queryParams = buildQueryParams({
46
72
  appId: opt.appId,
47
- startTime: (_opt$data = opt.data) === null || _opt$data === void 0 || (_opt$data = _opt$data[0]) === null || _opt$data === void 0 ? void 0 : _opt$data.timestamp,
48
- endTime: (_opt$data2 = opt.data) === null || _opt$data2 === void 0 || (_opt$data2 = _opt$data2[lastIndex]) === null || _opt$data2 === void 0 ? void 0 : _opt$data2.timestamp
49
- }; // 从配置中获取需要上报的参数名称列表
50
- config = (0, _config.getConfig)();
51
- paramsToReport = config.urlParamsToCache || ['taskId']; // 默认上报taskId
52
- // 添加缓存的参数到查询字符串中
53
- paramsToReport.forEach(function (paramName) {
54
- var paramValue = getCachedParam(paramName);
55
- if (paramValue) {
56
- queryParams[paramName] = paramValue;
57
- }
73
+ deviceId: opt.deviceId,
74
+ data: opt.data
58
75
  });
59
76
  queryString = new URLSearchParams(queryParams);
60
77
  api = "".concat(opt.url).concat(queryString ? "?".concat(queryString) : '');
@@ -63,33 +80,33 @@ var upload = exports.upload = /*#__PURE__*/function () {
63
80
 
64
81
  // 获取自定义请求头
65
82
  customHeaders = (0, _net.getCustomHeaders)();
66
- _context.next = 13;
83
+ _context.next = 8;
67
84
  return (0, _request.post)(api, formData, {
68
85
  headers: customHeaders
69
86
  });
70
- case 13:
87
+ case 8:
71
88
  response = _context.sent;
72
- _context.prev = 14;
89
+ _context.prev = 9;
73
90
  responseData = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
74
- _context.next = 21;
91
+ _context.next = 16;
75
92
  break;
76
- case 18:
77
- _context.prev = 18;
78
- _context.t0 = _context["catch"](14);
93
+ case 13:
94
+ _context.prev = 13;
95
+ _context.t0 = _context["catch"](9);
79
96
  return _context.abrupt("return");
80
- case 21:
97
+ case 16:
81
98
  if (!(responseData && _typeof(responseData) === 'object' && responseData.success === false)) {
82
- _context.next = 25;
99
+ _context.next = 20;
83
100
  break;
84
101
  }
85
102
  error = new Error(responseData.errorMessage || 'Upload failed with success=false'); // 将完整的响应数据附加到错误对象上
86
103
  error.responseData = responseData;
87
104
  throw error;
88
- case 25:
105
+ case 20:
89
106
  case "end":
90
107
  return _context.stop();
91
108
  }
92
- }, _callee, null, [[14, 18]]);
109
+ }, _callee, null, [[9, 13]]);
93
110
  }));
94
111
  return function upload(_x) {
95
112
  return _ref.apply(this, arguments);
@@ -41,6 +41,7 @@ export interface CdnConfig {
41
41
  ignoreRoutes?: string[];
42
42
  };
43
43
  packEvents?: boolean;
44
+ error?: boolean;
44
45
  captureMode?: 'full' | 'error';
45
46
  errorCapture?: ErrorCaptureConfig;
46
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB;IAElC,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,KAAK,CAAC,EAAE,CACJ,QAAQ,GACR,OAAO,GACP,OAAO,GACP,YAAY,GACZ,OAAO,GACP,KAAK,GACL,QAAQ,GACR,OAAO,GACP,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,MAAM,GACN,KAAK,GACL,OAAO,GACP,MAAM,GACN,SAAS,GACT,SAAS,GACT,OAAO,GACP,MAAM,CACT,EAAE,CAAC;IAEJ,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,gBAAgB,CAAC,EAAE;QAEjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAE3B,cAAc,CAAC,EAAE,MAAM,CAAC;QAExB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAGD,MAAM,WAAW,kBAAkB;IAEjC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAGD,MAAM,WAAW,SAAS;IAExB,MAAM,EAAE,OAAO,CAAC;IAEhB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,EAAE;QAET,MAAM,CAAC,EAAE,MAAM,CAAC;QAEhB,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAE7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAEhB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;KACxB,CAAC;IAGF,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,cAAc,EAAE,MAAM,CAAC;IAEvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAG5B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAGnC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAG9B,IAAI,CAAC,EAAE,OAAO,CAAC;IAGf,aAAa,CAAC,EAAE;QACd,MAAM,CAAC,EAAE,OAAO,CAAC;QAEjB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;IAGF,UAAU,CAAC,EAAE,OAAO,CAAC;IAGrB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAG/B,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AA8CD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAuC3E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAEhE;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,SAAS,CAErC;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBtE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB;IAElC,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,KAAK,CAAC,EAAE,CACJ,QAAQ,GACR,OAAO,GACP,OAAO,GACP,YAAY,GACZ,OAAO,GACP,KAAK,GACL,QAAQ,GACR,OAAO,GACP,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,MAAM,GACN,KAAK,GACL,OAAO,GACP,MAAM,GACN,SAAS,GACT,SAAS,GACT,OAAO,GACP,MAAM,CACT,EAAE,CAAC;IAEJ,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,gBAAgB,CAAC,EAAE;QAEjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAE3B,cAAc,CAAC,EAAE,MAAM,CAAC;QAExB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAGD,MAAM,WAAW,kBAAkB;IAEjC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAGD,MAAM,WAAW,SAAS;IAExB,MAAM,EAAE,OAAO,CAAC;IAEhB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,EAAE;QAET,MAAM,CAAC,EAAE,MAAM,CAAC;QAEhB,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAE7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAEhB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;KACxB,CAAC;IAGF,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,cAAc,EAAE,MAAM,CAAC;IAEvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAG5B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAGnC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAG9B,IAAI,CAAC,EAAE,OAAO,CAAC;IAGf,aAAa,CAAC,EAAE;QACd,MAAM,CAAC,EAAE,OAAO,CAAC;QAEjB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;IAGF,UAAU,CAAC,EAAE,OAAO,CAAC;IAGrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAGhB,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAG/B,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AA+CD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAuC3E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAEhE;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,SAAS,CAErC;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBtE"}
@@ -62,6 +62,8 @@ var DEFAULT_CONFIG = {
62
62
  // 默认不使用rrweb的packFn压缩事件数据
63
63
  clearStorageBeforeRecord: true,
64
64
  // 默认在开始录制前清空存储数据
65
+ error: false,
66
+ // 默认不启用错误监听上报,错误采集模式下默认true
65
67
  captureMode: 'full',
66
68
  // 默认全量采集模式
67
69
  errorCapture: {
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/lib/error.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAc/C;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAElE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAErD;AAGD,eAAO,MAAM,oBAAoB,SAAU,GAAG,SAmB7C,CAAC;AAGF,wBAAgB,gBAAgB,SA4I/B;AAGD,wBAAgB,mBAAmB,SAgBlC"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/lib/error.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAS/C;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAElE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAErD;AAGD,eAAO,MAAM,oBAAoB,SAAU,GAAG,SAmB7C,CAAC;AAqEF,wBAAgB,gBAAgB,SAS/B;AAGD,wBAAgB,mBAAmB,SAWlC"}