@pluve/logger-sdk 0.0.7 → 0.0.8
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 +60 -20
- package/dist/cjs/capture/jsError.js +48 -0
- package/dist/cjs/capture/promiseError.js +49 -0
- package/dist/cjs/capture/resourceError.js +48 -0
- package/dist/cjs/capture/wechatError.js +95 -0
- package/dist/cjs/compress/compression.js +84 -0
- package/dist/cjs/config/index.js +55 -0
- package/dist/cjs/core/fingerprint.js +36 -0
- package/dist/cjs/core/httpClient.js +96 -0
- package/dist/cjs/core/loggerSDK.js +641 -0
- package/dist/cjs/core/queueManager.js +249 -0
- package/dist/cjs/core/retryManager.js +127 -0
- package/dist/cjs/index.js +29 -0
- package/dist/cjs/logger-sdk.mermaid +84 -0
- package/dist/cjs/logger-sdk.svg +1 -0
- package/dist/cjs/stack/stacktrace.js +48 -0
- package/dist/cjs/transport/beaconTransport.js +64 -0
- package/dist/cjs/transport/pixelImageTransport.js +100 -0
- package/dist/cjs/transport/transport.js +17 -0
- package/dist/cjs/transport/transportAdapter.js +56 -0
- package/dist/cjs/transport/wechatTransport.js +103 -0
- package/dist/cjs/types/api.js +17 -0
- package/dist/cjs/types/env.js +17 -0
- package/dist/cjs/types/external.d.ts +21 -0
- package/dist/cjs/types/logEvent.js +17 -0
- package/dist/cjs/types/logEventLevel.js +17 -0
- package/dist/cjs/types/sdkOptions.js +17 -0
- package/dist/cjs/types/trackOptions.js +17 -0
- package/dist/cjs/utils/environment.js +183 -0
- package/dist/cjs/utils/session.js +31 -0
- package/dist/cjs/utils/tools.js +82 -0
- package/dist/cjs/utils/uuid.js +35 -0
- package/dist/esm/capture/jsError.js +45 -0
- package/dist/esm/capture/promiseError.js +46 -0
- package/dist/esm/capture/resourceError.js +24 -0
- package/dist/esm/capture/wechatError.js +92 -0
- package/dist/esm/compress/compression.js +82 -0
- package/dist/esm/config/index.js +28 -0
- package/dist/esm/core/fingerprint.js +12 -0
- package/dist/esm/core/httpClient.js +95 -0
- package/dist/esm/core/loggerSDK.js +650 -0
- package/dist/esm/core/queueManager.js +269 -0
- package/dist/esm/core/retryManager.js +129 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/logger-sdk.mermaid +84 -0
- package/dist/esm/logger-sdk.svg +1 -0
- package/dist/esm/stack/stacktrace.js +37 -0
- package/dist/esm/transport/beaconTransport.js +81 -0
- package/dist/esm/transport/pixelImageTransport.js +99 -0
- package/dist/esm/transport/transport.js +0 -0
- package/dist/esm/transport/transportAdapter.js +32 -0
- package/dist/esm/transport/wechatTransport.js +120 -0
- package/dist/esm/types/api.js +0 -0
- package/dist/esm/types/env.js +0 -0
- package/dist/esm/types/external.d.ts +21 -0
- package/dist/esm/types/logEvent.js +0 -0
- package/dist/esm/types/logEventLevel.js +0 -0
- package/dist/esm/types/sdkOptions.js +0 -0
- package/dist/esm/types/trackOptions.js +0 -0
- package/dist/esm/utils/environment.js +154 -0
- package/dist/esm/utils/session.js +7 -0
- package/dist/esm/utils/tools.js +76 -0
- package/dist/esm/utils/uuid.js +11 -0
- package/dist/types/capture/jsError.d.ts +2 -0
- package/dist/types/capture/promiseError.d.ts +2 -0
- package/dist/types/capture/resourceError.d.ts +2 -0
- package/dist/types/capture/wechatError.d.ts +3 -0
- package/dist/types/compress/compression.d.ts +10 -0
- package/dist/types/config/index.d.ts +9 -0
- package/dist/types/core/fingerprint.d.ts +8 -0
- package/dist/types/core/httpClient.d.ts +11 -0
- package/dist/{loggerSDK.d.ts → types/core/loggerSDK.d.ts} +27 -2
- package/dist/{queueManager.d.ts → types/core/queueManager.d.ts} +9 -1
- package/dist/{retryManager.d.ts → types/core/retryManager.d.ts} +0 -4
- package/dist/types/index.d.ts +1 -0
- package/dist/types/stack/stacktrace.d.ts +2 -0
- package/dist/types/transport/beaconTransport.d.ts +11 -0
- package/dist/types/transport/pixelImageTransport.d.ts +11 -0
- package/dist/types/transport/transport.d.ts +14 -0
- package/dist/types/transport/transportAdapter.d.ts +10 -0
- package/dist/types/transport/wechatTransport.d.ts +11 -0
- package/dist/types/types/api.d.ts +12 -0
- package/dist/types/types/env.d.ts +14 -0
- package/dist/types/types/logEvent.d.ts +57 -0
- package/dist/types/types/logEventLevel.d.ts +2 -0
- package/dist/{types.d.ts → types/types/sdkOptions.d.ts} +23 -42
- package/dist/types/types/trackOptions.d.ts +7 -0
- package/dist/types/utils/environment.d.ts +21 -0
- package/dist/types/utils/session.d.ts +1 -0
- package/dist/types/utils/tools.d.ts +12 -0
- package/dist/types/utils/uuid.d.ts +7 -0
- package/dist/umd/logger-sdk.min.js +1 -0
- package/package.json +29 -5
- package/dist/index.d.ts +0 -10
- package/dist/index.js +0 -13
- package/dist/loggerSDK.js +0 -560
- package/dist/queueManager.js +0 -186
- package/dist/retryManager.js +0 -224
- package/dist/transportAdapter.d.ts +0 -51
- package/dist/transportAdapter.js +0 -315
- package/dist/types.js +0 -1
- package/dist/utils.d.ts +0 -52
- package/dist/utils.js +0 -348
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/core/queueManager.ts
|
|
30
|
+
var queueManager_exports = {};
|
|
31
|
+
__export(queueManager_exports, {
|
|
32
|
+
QueueManager: () => QueueManager
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(queueManager_exports);
|
|
35
|
+
var import_environment = require("../utils/environment");
|
|
36
|
+
var import_tools = require("../utils/tools");
|
|
37
|
+
var QueueManager = class {
|
|
38
|
+
constructor(options) {
|
|
39
|
+
this.queue = [];
|
|
40
|
+
this.localforage = null;
|
|
41
|
+
this.opts = options;
|
|
42
|
+
this.storageKey = `${options.storagePrefix}_queue`;
|
|
43
|
+
this.loadLocalForage().then(() => {
|
|
44
|
+
if (this.opts.enableStorage) {
|
|
45
|
+
this.loadFromStorage();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async loadLocalForage() {
|
|
50
|
+
try {
|
|
51
|
+
if ((0, import_environment.isBrowser)()) {
|
|
52
|
+
import("localforage").then((res) => {
|
|
53
|
+
this.localforage = res;
|
|
54
|
+
(0, import_tools.logDebug)(!!this.opts.debug, res);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
} catch (e) {
|
|
58
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "localforage load error", e);
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 添加日志到队列
|
|
64
|
+
*/
|
|
65
|
+
enqueue(event) {
|
|
66
|
+
if (this.queue.length >= this.opts.maxSize) {
|
|
67
|
+
this.queue.shift();
|
|
68
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Queue full, dropped oldest event");
|
|
69
|
+
}
|
|
70
|
+
this.queue.push(event);
|
|
71
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Enqueued event", event);
|
|
72
|
+
if (this.opts.enableStorage) {
|
|
73
|
+
this.saveToStorage();
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 批量获取日志(不移除)
|
|
79
|
+
*/
|
|
80
|
+
peek(count) {
|
|
81
|
+
return this.queue.slice(0, count);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 批量移除日志
|
|
85
|
+
*/
|
|
86
|
+
dequeue(count) {
|
|
87
|
+
const items = this.queue.splice(0, count);
|
|
88
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Dequeued ${items.length} events`);
|
|
89
|
+
if (this.opts.enableStorage) {
|
|
90
|
+
this.saveToStorage();
|
|
91
|
+
}
|
|
92
|
+
return items;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 获取队列长度
|
|
96
|
+
*/
|
|
97
|
+
size() {
|
|
98
|
+
return this.queue.length;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 清空队列
|
|
102
|
+
*/
|
|
103
|
+
clear() {
|
|
104
|
+
this.queue = [];
|
|
105
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Queue cleared");
|
|
106
|
+
if (this.opts.enableStorage) {
|
|
107
|
+
this.removeFromStorage();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 从持久化存储加载队列
|
|
112
|
+
*/
|
|
113
|
+
async loadFromStorage() {
|
|
114
|
+
try {
|
|
115
|
+
let stored = null;
|
|
116
|
+
if ((0, import_environment.isWeChatMiniProgram)()) {
|
|
117
|
+
stored = wx.getStorageSync(this.storageKey);
|
|
118
|
+
} else if ((0, import_environment.isBrowser)()) {
|
|
119
|
+
if (!this.localforage) {
|
|
120
|
+
await this.loadLocalForage();
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const items = this.localforage ? await this.localforage.getItem(this.storageKey) : null;
|
|
124
|
+
if (Array.isArray(items)) {
|
|
125
|
+
this.queue = items.slice(0, this.opts.maxSize);
|
|
126
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Loaded ${this.queue.length} events from IndexedDB`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
} catch (err) {
|
|
130
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "IndexedDB load error, falling back to localStorage", err);
|
|
131
|
+
}
|
|
132
|
+
if (typeof localStorage !== "undefined") {
|
|
133
|
+
const ls = localStorage.getItem(this.storageKey);
|
|
134
|
+
if (ls) {
|
|
135
|
+
try {
|
|
136
|
+
const parsed = JSON.parse(ls);
|
|
137
|
+
if (Array.isArray(parsed)) {
|
|
138
|
+
this.queue = parsed.slice(0, this.opts.maxSize);
|
|
139
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Loaded ${this.queue.length} events from localStorage`);
|
|
140
|
+
}
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (stored) {
|
|
148
|
+
const parsed = JSON.parse(stored);
|
|
149
|
+
if (Array.isArray(parsed)) {
|
|
150
|
+
this.queue = parsed.slice(0, this.opts.maxSize);
|
|
151
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Loaded ${this.queue.length} events from storage`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Failed to load queue from storage", error);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 保存队列到持久化存储
|
|
160
|
+
*/
|
|
161
|
+
saveToStorage() {
|
|
162
|
+
try {
|
|
163
|
+
const data = (0, import_tools.safeStringify)(this.queue);
|
|
164
|
+
if ((0, import_environment.isWeChatMiniProgram)()) {
|
|
165
|
+
wx.setStorageSync(this.storageKey, data);
|
|
166
|
+
} else if ((0, import_environment.isBrowser)()) {
|
|
167
|
+
const saveToLocalStorage = () => {
|
|
168
|
+
if (typeof localStorage !== "undefined") {
|
|
169
|
+
localStorage.setItem(this.storageKey, data);
|
|
170
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Saved ${this.queue.length} events to localStorage`);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
if (!this.localforage) {
|
|
174
|
+
this.loadLocalForage().then(() => {
|
|
175
|
+
if (this.localforage) {
|
|
176
|
+
return this.localforage.setItem(this.storageKey, this.queue).then(() => {
|
|
177
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Saved ${this.queue.length} events to IndexedDB`);
|
|
178
|
+
}).catch((err) => {
|
|
179
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "IndexedDB save error, falling back to localStorage", err);
|
|
180
|
+
saveToLocalStorage();
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
saveToLocalStorage();
|
|
184
|
+
return null;
|
|
185
|
+
}).catch((err) => {
|
|
186
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "IndexedDB save error, falling back to localStorage", err);
|
|
187
|
+
saveToLocalStorage();
|
|
188
|
+
});
|
|
189
|
+
} else {
|
|
190
|
+
this.localforage.setItem(this.storageKey, this.queue).then(() => {
|
|
191
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Saved ${this.queue.length} events to IndexedDB`);
|
|
192
|
+
}).catch((err) => {
|
|
193
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "IndexedDB save error, falling back to localStorage", err);
|
|
194
|
+
saveToLocalStorage();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
} catch (error) {
|
|
199
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Failed to save queue to storage", error);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* 从持久化存储移除队列
|
|
204
|
+
*/
|
|
205
|
+
removeFromStorage() {
|
|
206
|
+
try {
|
|
207
|
+
if ((0, import_environment.isWeChatMiniProgram)()) {
|
|
208
|
+
wx.removeStorageSync(this.storageKey);
|
|
209
|
+
} else if ((0, import_environment.isBrowser)()) {
|
|
210
|
+
const removeFromLocalStorage = () => {
|
|
211
|
+
if (typeof localStorage !== "undefined") {
|
|
212
|
+
localStorage.removeItem(this.storageKey);
|
|
213
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Removed queue from localStorage");
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
if (!this.localforage) {
|
|
217
|
+
this.loadLocalForage().then(() => {
|
|
218
|
+
if (this.localforage) {
|
|
219
|
+
return this.localforage.removeItem(this.storageKey).then(() => {
|
|
220
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Removed queue from IndexedDB");
|
|
221
|
+
}).catch((err) => {
|
|
222
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "IndexedDB remove error, falling back to localStorage", err);
|
|
223
|
+
removeFromLocalStorage();
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
removeFromLocalStorage();
|
|
227
|
+
return null;
|
|
228
|
+
}).catch((err) => {
|
|
229
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "IndexedDB remove error, falling back to localStorage", err);
|
|
230
|
+
removeFromLocalStorage();
|
|
231
|
+
});
|
|
232
|
+
} else {
|
|
233
|
+
this.localforage.removeItem(this.storageKey).then(() => {
|
|
234
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Removed queue from IndexedDB");
|
|
235
|
+
}).catch((err) => {
|
|
236
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "IndexedDB remove error, falling back to localStorage", err);
|
|
237
|
+
removeFromLocalStorage();
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
} catch (error) {
|
|
242
|
+
(0, import_tools.logDebug)(!!this.opts.debug, "Failed to remove queue from storage", error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
247
|
+
0 && (module.exports = {
|
|
248
|
+
QueueManager
|
|
249
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/core/retryManager.ts
|
|
20
|
+
var retryManager_exports = {};
|
|
21
|
+
__export(retryManager_exports, {
|
|
22
|
+
RetryManager: () => RetryManager
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(retryManager_exports);
|
|
25
|
+
var import_tools = require("../utils/tools");
|
|
26
|
+
var RetryManager = class {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.retryingTasks = /* @__PURE__ */ new Map();
|
|
29
|
+
this.opts = options;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 执行带重试的任务
|
|
33
|
+
* @param taskId - 任务唯一标识
|
|
34
|
+
* @param fn - 要执行的异步函数
|
|
35
|
+
* @returns Promise
|
|
36
|
+
*/
|
|
37
|
+
async executeWithRetry(taskId, fn) {
|
|
38
|
+
if (this.retryingTasks.has(taskId)) {
|
|
39
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Task ${taskId} already retrying, skipped`);
|
|
40
|
+
throw new Error(`Task ${taskId} already retrying`);
|
|
41
|
+
}
|
|
42
|
+
const task = {
|
|
43
|
+
id: taskId,
|
|
44
|
+
fn,
|
|
45
|
+
retries: 0,
|
|
46
|
+
maxRetries: this.opts.maxRetries,
|
|
47
|
+
baseDelay: this.opts.baseDelay,
|
|
48
|
+
useBackoff: this.opts.useBackoff
|
|
49
|
+
};
|
|
50
|
+
this.retryingTasks.set(taskId, task);
|
|
51
|
+
try {
|
|
52
|
+
const result = await this.executeTask(task);
|
|
53
|
+
this.retryingTasks.delete(taskId);
|
|
54
|
+
return result;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
this.retryingTasks.delete(taskId);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 执行任务(带重试逻辑)
|
|
62
|
+
*/
|
|
63
|
+
async executeTask(task) {
|
|
64
|
+
while (task.retries <= task.maxRetries) {
|
|
65
|
+
try {
|
|
66
|
+
const result = await task.fn();
|
|
67
|
+
if (task.retries > 0) {
|
|
68
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Task ${task.id} succeeded after ${task.retries} retries`);
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
task.retries += 1;
|
|
73
|
+
if (task.retries > task.maxRetries) {
|
|
74
|
+
(0, import_tools.logDebug)(!!this.opts.debug, `Task ${task.id} failed after ${task.maxRetries} retries`);
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
const delay = RetryManager.calculateDelay(task.retries, task.baseDelay, task.useBackoff);
|
|
78
|
+
(0, import_tools.logDebug)(
|
|
79
|
+
!!this.opts.debug,
|
|
80
|
+
`Task ${task.id} failed (attempt ${task.retries}/${task.maxRetries}), retrying in ${delay}ms`
|
|
81
|
+
);
|
|
82
|
+
await RetryManager.sleep(delay);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`Task ${task.id} exceeded max retries`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 计算延迟时间
|
|
89
|
+
* @param attempt - 当前重试次数
|
|
90
|
+
* @param baseDelay - 基础延迟时间
|
|
91
|
+
* @param useBackoff - 是否使用指数退避
|
|
92
|
+
* @returns 延迟时间(毫秒)
|
|
93
|
+
*/
|
|
94
|
+
static calculateDelay(attempt, baseDelay, useBackoff) {
|
|
95
|
+
if (!useBackoff) {
|
|
96
|
+
return baseDelay;
|
|
97
|
+
}
|
|
98
|
+
const factor = 2 ** (attempt - 1);
|
|
99
|
+
const delay = baseDelay * factor;
|
|
100
|
+
const jitterRatio = 0.3;
|
|
101
|
+
const maxDelay = 3e4;
|
|
102
|
+
const jitter = Math.random() * jitterRatio * delay;
|
|
103
|
+
return Math.min(delay + jitter, maxDelay);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 睡眠函数
|
|
107
|
+
*/
|
|
108
|
+
static sleep(ms) {
|
|
109
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 获取正在重试的任务数量
|
|
113
|
+
*/
|
|
114
|
+
getRetryingCount() {
|
|
115
|
+
return this.retryingTasks.size;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 清空所有重试任务
|
|
119
|
+
*/
|
|
120
|
+
clear() {
|
|
121
|
+
this.retryingTasks.clear();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
125
|
+
0 && (module.exports = {
|
|
126
|
+
RetryManager
|
|
127
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/index.ts
|
|
20
|
+
var src_exports = {};
|
|
21
|
+
__export(src_exports, {
|
|
22
|
+
LoggerSDK: () => import_loggerSDK.LoggerSDK
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(src_exports);
|
|
25
|
+
var import_loggerSDK = require("./core/loggerSDK");
|
|
26
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
27
|
+
0 && (module.exports = {
|
|
28
|
+
LoggerSDK
|
|
29
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
flowchart TD
|
|
2
|
+
A[初始化 SDK] --> B[设置选项(批量/重试/gzip/自动采集)]
|
|
3
|
+
B --> C{启用批量?}
|
|
4
|
+
C -->|是| D[创建队列管理器并加载存储]
|
|
5
|
+
C -->|否| E[跳过队列管理器]
|
|
6
|
+
B --> F{启用重试?}
|
|
7
|
+
F -->|是| G[创建重试管理器]
|
|
8
|
+
F -->|否| H[跳过重试管理器]
|
|
9
|
+
B --> I[选择传输适配器]
|
|
10
|
+
I --> J{运行环境}
|
|
11
|
+
J -->|微信小程序| K[WechatTransport]
|
|
12
|
+
J -->|浏览器| L{支持 Beacon?}
|
|
13
|
+
L -->|是| M[BeaconTransport]
|
|
14
|
+
L -->|否| N[PixelImageTransport]
|
|
15
|
+
B --> O[生成会话ID]
|
|
16
|
+
B --> P[收集环境标签]
|
|
17
|
+
B --> Q[注册 SDK]
|
|
18
|
+
Q --> R[接收初始化数据: 开关/等级/采样率]
|
|
19
|
+
R --> S{启用批量?}
|
|
20
|
+
S -->|是| T[启动批量定时器]
|
|
21
|
+
R --> U[挂载卸载/可见性事件处理]
|
|
22
|
+
U --> V{enableAutoCapture?}
|
|
23
|
+
V -->|是| V1[按 autoCapture: 注册 js/promise/resource/wechat]
|
|
24
|
+
V -->|否| V2[跳过自动采集]
|
|
25
|
+
|
|
26
|
+
subgraph 采集与上报
|
|
27
|
+
W[调用 track 或自动采集] --> X{已初始化且未关闭?}
|
|
28
|
+
X -->|否| X1[跳过]
|
|
29
|
+
X -->|是| X2{3秒去重窗口?}
|
|
30
|
+
X2 -->|重复| X3[跳过]
|
|
31
|
+
X2 -->|非重复| Y{shouldSend 采样?}
|
|
32
|
+
Y -->|否| Y1[采样丢弃]
|
|
33
|
+
Y -->|是| Z[构建 LogEvent]
|
|
34
|
+
Z --> AA{启用批量?}
|
|
35
|
+
AA -->|是| AB[enqueue 入队]
|
|
36
|
+
AB --> AC{队列达到批量阈值?}
|
|
37
|
+
AC -->|是| AD[flush 刷新]
|
|
38
|
+
AC -->|否| AE[等待定时器/下一次触发]
|
|
39
|
+
AA -->|否| AF[sendEvent 直接发送]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
subgraph 批量刷新
|
|
43
|
+
AD --> AG[peek 读取待发事件]
|
|
44
|
+
AG --> AH[sendBatch 批量发送]
|
|
45
|
+
AH --> AI[按 appId & stage 分组并分块]
|
|
46
|
+
AI --> AJ[transporter.send(并发收集)]
|
|
47
|
+
AJ --> AK[dequeue 成功后出队]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
subgraph 传输细节
|
|
51
|
+
K --> K1[字符串化; 启用 gzip 时压缩成 Base64; wx.request POST]
|
|
52
|
+
M --> M1{启用 gzip? 且满足批量条件}
|
|
53
|
+
M1 -->|是| M2[压缩 items 为 Base64 字符串; 替换 body 为 「...payload, items: Base64」; 设置 Content-Type]
|
|
54
|
+
M1 -->|否| M3[直接 JSON body; Blob 包裹; sendBeacon POST]
|
|
55
|
+
N --> N1[字符串化 items; gzip: Base64 / btoa / encodeURIComponent 回退; Image GET]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
subgraph 压缩流程
|
|
59
|
+
C1[gzipCompress(data)] --> C2{支持 CompressionStream?}
|
|
60
|
+
C2 -->|是| C3[CompressionStream('gzip') 流式压缩后 Base64]
|
|
61
|
+
C2 -->|否| C4[fflate.gzipSync + Base64.fromUint8Array]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
subgraph 定时与卸载
|
|
65
|
+
T --> T1[setInterval 周期性 flush]
|
|
66
|
+
U --> U1[visibilitychange/pagehide/beforeunload 触发 flush]
|
|
67
|
+
V1 --> U2[销毁时统一 off(js/promise/resource/wechat)]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
subgraph 重试策略
|
|
71
|
+
AF --> R1{启用重试?}
|
|
72
|
+
R1 -->|是| R2[executeWithRetry(event.logId, sendFn)]
|
|
73
|
+
R1 -->|否| R3[直接 sendFn]
|
|
74
|
+
AH --> R4{启用重试?}
|
|
75
|
+
R4 -->|是| R5[executeWithRetry(batchId, sendFn)]
|
|
76
|
+
R4 -->|否| R6[直接 sendFn]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
subgraph 存储兼容
|
|
80
|
+
D --> D1{环境}
|
|
81
|
+
D1 -->|浏览器| D2[动态 import localforage 使用 IndexedDB; 失败回退 localStorage]
|
|
82
|
+
D2 --> D2a[如解析失败: 回退 globalThis.localforage]
|
|
83
|
+
D1 -->|微信小程序| D3[使用 wx.storage 同步 API]
|
|
84
|
+
end
|