@pluve/logger-sdk 0.0.1 → 0.0.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 +195 -76
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +14 -2
- package/dist/cjs/loggerSDK.d.ts +27 -20
- package/dist/cjs/loggerSDK.js +86 -354
- package/dist/cjs/transportAdapter.d.ts +51 -5
- package/dist/cjs/transportAdapter.js +133 -60
- package/dist/cjs/types.d.ts +37 -26
- package/dist/cjs/utils.d.ts +27 -2
- package/dist/cjs/utils.js +151 -12
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +4 -2
- package/dist/esm/loggerSDK.d.ts +27 -20
- package/dist/esm/loggerSDK.js +141 -674
- package/dist/esm/transportAdapter.d.ts +51 -5
- package/dist/esm/transportAdapter.js +260 -111
- package/dist/esm/types.d.ts +37 -26
- package/dist/esm/utils.d.ts +27 -2
- package/dist/esm/utils.js +190 -14
- package/dist/umd/logger-sdk.min.js +1 -1
- package/lib/dbQueue.js +133 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +9 -0
- package/lib/loggerSDK.d.ts +29 -0
- package/lib/loggerSDK.js +571 -0
- package/lib/storeAdapter.js +99 -0
- package/lib/transportAdapter.d.ts +66 -0
- package/lib/transportAdapter.js +406 -0
- package/lib/types.d.ts +35 -0
- package/lib/types.js +1 -0
- package/lib/utils.d.ts +5 -0
- package/lib/utils.js +50 -0
- package/package.json +8 -2
- package/dist/cjs/dbQueue.js +0 -88
- package/dist/cjs/storeAdapter.js +0 -64
- package/dist/esm/dbQueue.d.ts +0 -10
- package/dist/esm/dbQueue.js +0 -194
- package/dist/esm/storeAdapter.d.ts +0 -7
- package/dist/esm/storeAdapter.js +0 -139
- /package/{dist/cjs → lib}/dbQueue.d.ts +0 -0
- /package/{dist/cjs → lib}/storeAdapter.d.ts +0 -0
package/dist/cjs/loggerSDK.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
1
|
var __defProp = Object.defineProperty;
|
|
3
2
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
5
|
var __export = (target, all) => {
|
|
8
6
|
for (var name in all)
|
|
@@ -16,14 +14,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
14
|
}
|
|
17
15
|
return to;
|
|
18
16
|
};
|
|
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
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
18
|
|
|
29
19
|
// src/loggerSDK.ts
|
|
@@ -33,391 +23,133 @@ __export(loggerSDK_exports, {
|
|
|
33
23
|
default: () => loggerSDK_default
|
|
34
24
|
});
|
|
35
25
|
module.exports = __toCommonJS(loggerSDK_exports);
|
|
36
|
-
var import_dbQueue = __toESM(require("./dbQueue"));
|
|
37
26
|
var import_transportAdapter = require("./transportAdapter");
|
|
38
27
|
var import_utils = require("./utils");
|
|
39
|
-
var import_storeAdapter = require("./storeAdapter");
|
|
40
28
|
var LoggerSDK = class {
|
|
41
29
|
constructor(options) {
|
|
42
|
-
this.inMemoryQueue = [];
|
|
43
30
|
this.seq = 0;
|
|
44
|
-
this.timerId = null;
|
|
45
|
-
this.storage = null;
|
|
46
31
|
this.closed = false;
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
appId: options.appId || "",
|
|
52
|
-
env: options.env || (() => {
|
|
53
|
-
if ((0, import_utils.isWeChatMiniProgram)())
|
|
54
|
-
return "wechat";
|
|
55
|
-
if ((0, import_utils.isBrowser)())
|
|
56
|
-
return "h5";
|
|
57
|
-
return "unknown";
|
|
58
|
-
})(),
|
|
59
|
-
batchSize: options.batchSize || 10,
|
|
60
|
-
flushInterval: options.flushInterval || 5e3,
|
|
61
|
-
retryCount: options.retryCount || 3,
|
|
62
|
-
retryBase: options.retryBase || 300,
|
|
63
|
-
storageKey: options.storageKey || "logger_sdk_cache_v2",
|
|
64
|
-
maxCacheSize: options.maxCacheSize || 2e3,
|
|
65
|
-
timeout: options.timeout || 1e4,
|
|
32
|
+
this.opts = {
|
|
33
|
+
endpoint: options.endpoint,
|
|
34
|
+
appId: options.appId || "unknown",
|
|
35
|
+
env: options.env || "dev",
|
|
66
36
|
debug: !!options.debug,
|
|
67
|
-
transport: options.transport || import_transportAdapter.defaultTransport,
|
|
68
|
-
globalHeaders: options.globalHeaders || {},
|
|
69
|
-
enableAutoPV: options.enableAutoPV !== false,
|
|
70
|
-
enablePerf: options.enablePerf !== false,
|
|
71
|
-
usePixel: options.usePixel || false,
|
|
72
37
|
pixelParam: options.pixelParam || "data",
|
|
73
38
|
maxPixelUrlLen: options.maxPixelUrlLen || 1900
|
|
74
39
|
};
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
77
|
-
if (this.env === "wechat")
|
|
78
|
-
this.storage = (0, import_storeAdapter.wechatStorage)(this.opts.storageKey);
|
|
79
|
-
else if (this.env === "h5")
|
|
80
|
-
this.storage = (0, import_storeAdapter.browserStorage)(this.opts.storageKey);
|
|
81
|
-
else
|
|
82
|
-
this.storage = null;
|
|
83
|
-
if ((0, import_utils.isBrowser)() && (0, import_utils.isIndexedDBAvailable)()) {
|
|
84
|
-
this.idbQueue = new import_dbQueue.default("logger_sdk_db", "queue");
|
|
85
|
-
this.idbQueue.open().catch(() => {
|
|
86
|
-
this.idbQueue = null;
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
this.loadFromStorage().then(() => {
|
|
90
|
-
if (this.opts.flushInterval > 0)
|
|
91
|
-
this.startTimer();
|
|
92
|
-
});
|
|
93
|
-
this.attachGlobalHandlers();
|
|
94
|
-
if (this.opts.enableAutoPV && this.env === "h5")
|
|
95
|
-
this.installAutoPV();
|
|
96
|
-
if (this.opts.enablePerf && this.env === "h5") {
|
|
97
|
-
if (document.readyState === "complete")
|
|
98
|
-
this.collectPerf();
|
|
99
|
-
else
|
|
100
|
-
window.addEventListener("load", () => this.collectPerf());
|
|
101
|
-
}
|
|
40
|
+
this.envTags = this.collectEnvironmentTags();
|
|
41
|
+
this.attachUnloadHandlers();
|
|
102
42
|
}
|
|
103
43
|
logDebug(...args) {
|
|
104
44
|
if (this.opts.debug)
|
|
105
45
|
console.debug("[LoggerSDK]", ...args);
|
|
106
46
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
47
|
+
/**
|
|
48
|
+
* 收集环境信息并生成 tags(仅在初始化时执行一次)
|
|
49
|
+
*/
|
|
50
|
+
collectEnvironmentTags() {
|
|
51
|
+
const envInfo = (0, import_utils.getEnvironmentInfo)();
|
|
52
|
+
const tags = {
|
|
53
|
+
platform: envInfo.platform
|
|
54
|
+
};
|
|
55
|
+
if (envInfo.platform === "browser" && envInfo.userAgent) {
|
|
56
|
+
const browserInfo = (0, import_utils.parseBrowserInfo)(envInfo.userAgent);
|
|
57
|
+
tags.browser = browserInfo.browser;
|
|
58
|
+
tags.browserVersion = browserInfo.browserVersion;
|
|
59
|
+
tags.os = browserInfo.os;
|
|
60
|
+
tags.osVersion = browserInfo.osVersion;
|
|
61
|
+
tags.screenWidth = envInfo.screenWidth;
|
|
62
|
+
tags.screenHeight = envInfo.screenHeight;
|
|
63
|
+
tags.language = envInfo.language;
|
|
64
|
+
} else if (envInfo.platform === "wechat" && envInfo.systemInfo) {
|
|
65
|
+
tags.brand = envInfo.systemInfo.brand;
|
|
66
|
+
tags.model = envInfo.systemInfo.model;
|
|
67
|
+
tags.system = envInfo.systemInfo.system;
|
|
68
|
+
tags.wechatVersion = envInfo.systemInfo.version;
|
|
69
|
+
tags.SDKVersion = envInfo.systemInfo.SDKVersion;
|
|
70
|
+
tags.screenWidth = envInfo.screenWidth;
|
|
71
|
+
tags.screenHeight = envInfo.screenHeight;
|
|
72
|
+
tags.language = envInfo.language;
|
|
129
73
|
}
|
|
74
|
+
this.logDebug("Environment tags collected:", tags);
|
|
75
|
+
return tags;
|
|
130
76
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}), this.opts.flushInterval);
|
|
136
|
-
}
|
|
137
|
-
stopTimer() {
|
|
138
|
-
if (!this.timerId)
|
|
139
|
-
return;
|
|
140
|
-
clearInterval(this.timerId);
|
|
141
|
-
this.timerId = null;
|
|
142
|
-
}
|
|
143
|
-
// 将事件入队(先到内存,再持久化)
|
|
144
|
-
async track(event, headers) {
|
|
77
|
+
/**
|
|
78
|
+
* 记录事件
|
|
79
|
+
*/
|
|
80
|
+
async track(eventType, message, options) {
|
|
145
81
|
if (this.closed)
|
|
146
82
|
return;
|
|
147
83
|
this.seq += 1;
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
level:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
this.logDebug("idb add fail", err);
|
|
84
|
+
const logEvent = {
|
|
85
|
+
eventType,
|
|
86
|
+
ts: (0, import_utils.now)(),
|
|
87
|
+
appId: this.opts.appId || "unknown",
|
|
88
|
+
env: this.opts.env || "dev",
|
|
89
|
+
level: (options == null ? void 0 : options.level) || "info",
|
|
90
|
+
message,
|
|
91
|
+
stack: options == null ? void 0 : options.stack,
|
|
92
|
+
url: (0, import_utils.getCurrentUrl)(),
|
|
93
|
+
userId: options == null ? void 0 : options.userId,
|
|
94
|
+
sessionId: (0, import_utils.getSessionId)(),
|
|
95
|
+
// 合并预收集的环境 tags 和用户自定义 tags
|
|
96
|
+
tags: {
|
|
97
|
+
...this.envTags,
|
|
98
|
+
...(options == null ? void 0 : options.tags) || {}
|
|
164
99
|
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
await this.flush(headers).catch(() => {
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// flush:从队列中取一批发送(按 level 分 endpoint,支持部分成功剔除)
|
|
172
|
-
async flush(extraHeaders) {
|
|
173
|
-
if (this.closed)
|
|
174
|
-
return;
|
|
175
|
-
if (this.inMemoryQueue.length === 0)
|
|
176
|
-
return;
|
|
177
|
-
if (this.flushing)
|
|
178
|
-
return;
|
|
179
|
-
this.flushing = true;
|
|
100
|
+
};
|
|
101
|
+
this.logDebug("track", logEvent);
|
|
180
102
|
try {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const level = ev.level || "info";
|
|
185
|
-
(groups[level] = groups[level] || []).push(ev);
|
|
186
|
-
});
|
|
187
|
-
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
188
|
-
const sendGroup = (level, events) => {
|
|
189
|
-
const endpoint = this.opts.endpoints[level] || this.opts.endpoints.default;
|
|
190
|
-
const payload = { appId: this.opts.appId, env: this.env, ts: (0, import_utils.now)(), level, events };
|
|
191
|
-
const maxTry = this.opts.retryCount;
|
|
192
|
-
const attemptOnce = (attempt) => {
|
|
193
|
-
const transportOpts = { ...this.opts, endpoint, headers: { ...this.opts.globalHeaders || {}, ...extraHeaders || {} } };
|
|
194
|
-
return this.opts.transport(payload, transportOpts).then(() => true).catch(async (err) => {
|
|
195
|
-
const next = attempt + 1;
|
|
196
|
-
this.logDebug("send fail", level, next, err);
|
|
197
|
-
if (next > maxTry)
|
|
198
|
-
return false;
|
|
199
|
-
const wait = (this.opts.retryBase || 300) * 2 ** (next - 1);
|
|
200
|
-
await delay(wait);
|
|
201
|
-
return attemptOnce(next);
|
|
202
|
-
});
|
|
203
|
-
};
|
|
204
|
-
return attemptOnce(0).then((ok) => ({ ok, level, events }));
|
|
205
|
-
};
|
|
206
|
-
const results = await Promise.all(Object.keys(groups).map((level) => sendGroup(level, groups[level])));
|
|
207
|
-
const successLevels = new Set(results.filter((r) => r.ok).map((r) => r.level));
|
|
208
|
-
const allOk = results.length > 0 && results.every((r) => r.ok);
|
|
209
|
-
if (!allOk && successLevels.size === 0) {
|
|
210
|
-
this.logDebug("batch send failed, keep batch in queue");
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
const removeSeq = new Set(batch.filter((e) => successLevels.has(e.level || "info")).map((e) => e.seq));
|
|
214
|
-
this.inMemoryQueue = this.inMemoryQueue.filter((x) => !removeSeq.has(x.seq));
|
|
215
|
-
await this.persistToStorage();
|
|
216
|
-
if (allOk && this.idbQueue) {
|
|
217
|
-
try {
|
|
218
|
-
await this.idbQueue.clear();
|
|
219
|
-
} catch (e) {
|
|
220
|
-
this.logDebug("idb clear fail", e);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
} finally {
|
|
224
|
-
this.flushing = false;
|
|
103
|
+
await (0, import_transportAdapter.defaultTransport)(logEvent, this.opts);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
this.logDebug("track failed", error);
|
|
225
106
|
}
|
|
226
107
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
safety += 1;
|
|
233
|
-
if (this.inMemoryQueue.length === 0 || safety >= 200)
|
|
234
|
-
return resolve();
|
|
235
|
-
if (!this.flushing) {
|
|
236
|
-
try {
|
|
237
|
-
await this.flush();
|
|
238
|
-
} catch {
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
setTimeout(tick, 50);
|
|
242
|
-
};
|
|
243
|
-
tick();
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
async identify(user) {
|
|
247
|
-
this.opts.appId = user && user.appId || this.opts.appId;
|
|
248
|
-
this.logDebug("identify", user);
|
|
249
|
-
}
|
|
250
|
-
async setCommon(params) {
|
|
251
|
-
Object.assign(this.opts, params);
|
|
252
|
-
this.logDebug("setCommon", params);
|
|
108
|
+
/**
|
|
109
|
+
* 设置用户信息
|
|
110
|
+
*/
|
|
111
|
+
identify(userId) {
|
|
112
|
+
this.logDebug("identify", userId);
|
|
253
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* 销毁实例
|
|
116
|
+
*/
|
|
254
117
|
destroy() {
|
|
255
|
-
this.stopTimer();
|
|
256
118
|
this.closed = true;
|
|
257
119
|
}
|
|
258
|
-
// ==========
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
win.addEventListener && win.addEventListener("unhandledrejection", (ev) => {
|
|
269
|
-
try {
|
|
270
|
-
this.track({ type: "error", level: "error", ctx: { reason: ev.reason && (ev.reason.stack || ev.reason) } });
|
|
271
|
-
} catch {
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
win.addEventListener && win.addEventListener(
|
|
275
|
-
"error",
|
|
276
|
-
(ev) => {
|
|
277
|
-
if (ev.target && (ev.target.src || ev.target.href)) {
|
|
278
|
-
try {
|
|
279
|
-
this.track({ type: "error", level: "warn", ctx: { resource: ev.target.src || ev.target.href, tag: ev.target.tagName } });
|
|
280
|
-
} catch {
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
},
|
|
284
|
-
true
|
|
285
|
-
);
|
|
286
|
-
document.addEventListener && document.addEventListener("visibilitychange", () => {
|
|
287
|
-
try {
|
|
288
|
-
if (document.visibilityState === "hidden")
|
|
289
|
-
this.flushBeacon();
|
|
290
|
-
} catch {
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
win.addEventListener && win.addEventListener("pagehide", () => {
|
|
294
|
-
try {
|
|
295
|
-
this.flushBeacon();
|
|
296
|
-
} catch {
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
win.addEventListener && win.addEventListener("beforeunload", () => {
|
|
300
|
-
try {
|
|
301
|
-
this.flushBeacon();
|
|
302
|
-
} catch {
|
|
303
|
-
}
|
|
304
|
-
});
|
|
120
|
+
// ========== 自动采集 ===========
|
|
121
|
+
/**
|
|
122
|
+
* 监听页面卸载事件
|
|
123
|
+
*/
|
|
124
|
+
attachUnloadHandlers() {
|
|
125
|
+
if ((0, import_utils.isWeChatMiniProgram)()) {
|
|
126
|
+
this.logDebug("WeChat MiniProgram environment detected");
|
|
127
|
+
return;
|
|
305
128
|
}
|
|
306
|
-
}
|
|
307
|
-
// 自动 PV(single-page 支持简单的 history 池监听)
|
|
308
|
-
installAutoPV() {
|
|
309
129
|
if (!(0, import_utils.isBrowser)())
|
|
310
130
|
return;
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
const { replaceState } = history;
|
|
314
|
-
const onUrlChange = () => {
|
|
131
|
+
const win = window;
|
|
132
|
+
document.addEventListener && document.addEventListener("visibilitychange", () => {
|
|
315
133
|
try {
|
|
316
|
-
|
|
134
|
+
if (document.visibilityState === "hidden") {
|
|
135
|
+
console.log("Page hidden");
|
|
136
|
+
}
|
|
317
137
|
} catch {
|
|
318
138
|
}
|
|
319
|
-
};
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
history.replaceState = function(...args) {
|
|
325
|
-
replaceState.apply(this, args);
|
|
326
|
-
window.dispatchEvent(new Event("locationchange"));
|
|
327
|
-
};
|
|
328
|
-
window.addEventListener("popstate", () => window.dispatchEvent(new Event("locationchange")));
|
|
329
|
-
window.addEventListener("locationchange", onUrlChange);
|
|
330
|
-
onUrlChange();
|
|
331
|
-
}
|
|
332
|
-
// 性能采集(Navigation timing + Paint)
|
|
333
|
-
collectPerf() {
|
|
334
|
-
if (!(0, import_utils.isBrowser)() || !("performance" in window))
|
|
335
|
-
return;
|
|
336
|
-
try {
|
|
337
|
-
const perf = window.performance;
|
|
338
|
-
const nav = perf.getEntriesByType && perf.getEntriesByType("navigation") && perf.getEntriesByType("navigation")[0];
|
|
339
|
-
const paints = perf.getEntriesByType ? perf.getEntriesByType("paint") : [];
|
|
340
|
-
const data = {};
|
|
341
|
-
if (nav) {
|
|
342
|
-
data.ttfb = nav.responseStart - nav.requestStart;
|
|
343
|
-
data.domContentLoaded = nav.domContentLoadedEventEnd - nav.startTime;
|
|
344
|
-
data.load = nav.loadEventEnd - nav.startTime;
|
|
345
|
-
} else if (perf.timing) {
|
|
346
|
-
const t = perf.timing;
|
|
347
|
-
data.ttfb = t.responseStart - t.requestStart;
|
|
348
|
-
data.domContentLoaded = t.domContentLoadedEventEnd - t.navigationStart;
|
|
349
|
-
data.load = t.loadEventEnd - t.navigationStart;
|
|
350
|
-
}
|
|
351
|
-
if (paints && paints.length) {
|
|
352
|
-
paints.forEach((p) => {
|
|
353
|
-
data[p.name] = p.startTime;
|
|
354
|
-
});
|
|
139
|
+
});
|
|
140
|
+
win.addEventListener && win.addEventListener("pagehide", () => {
|
|
141
|
+
try {
|
|
142
|
+
console.log("Page hide");
|
|
143
|
+
} catch {
|
|
355
144
|
}
|
|
356
|
-
this.track({ type: "perf", level: "info", ctx: data });
|
|
357
|
-
} catch (e) {
|
|
358
|
-
this.logDebug("collect perf fail", e);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
flushBeacon() {
|
|
362
|
-
if (!(0, import_utils.isBrowser)())
|
|
363
|
-
return;
|
|
364
|
-
if (this.inMemoryQueue.length === 0)
|
|
365
|
-
return;
|
|
366
|
-
const groups = {};
|
|
367
|
-
this.inMemoryQueue.forEach((ev) => {
|
|
368
|
-
const level = ev.level || "info";
|
|
369
|
-
(groups[level] = groups[level] || []).push(ev);
|
|
370
145
|
});
|
|
371
|
-
|
|
372
|
-
const events = groups[level];
|
|
373
|
-
const endpoint = this.opts.endpoints[level] || this.opts.endpoints.default;
|
|
374
|
-
const payload = { appId: this.opts.appId, env: this.env, ts: (0, import_utils.now)(), level, events };
|
|
375
|
-
const transportOpts = {
|
|
376
|
-
...this.opts,
|
|
377
|
-
endpoint,
|
|
378
|
-
headers: { ...this.opts.globalHeaders || {} },
|
|
379
|
-
useBeacon: true,
|
|
380
|
-
usePixel: this.opts.usePixel,
|
|
381
|
-
pixelParam: this.opts.pixelParam,
|
|
382
|
-
maxPixelUrlLen: this.opts.maxPixelUrlLen
|
|
383
|
-
};
|
|
146
|
+
win.addEventListener && win.addEventListener("beforeunload", () => {
|
|
384
147
|
try {
|
|
385
|
-
|
|
148
|
+
console.log("Page unload");
|
|
386
149
|
} catch {
|
|
387
150
|
}
|
|
388
151
|
});
|
|
389
152
|
}
|
|
390
|
-
// 生成简单 Demo 页面(HTML 字符串),方便生成 demo 文档站点
|
|
391
|
-
// public generateDemoHtml(opts?: { scriptUrl?: string }) {
|
|
392
|
-
// const scriptUrl = (opts && opts.scriptUrl) || 'dist/index.umd.js';
|
|
393
|
-
// const html = ```
|
|
394
|
-
// <!doctype html>
|
|
395
|
-
// <html>
|
|
396
|
-
// <head>
|
|
397
|
-
// <meta charset="utf-8" />
|
|
398
|
-
// <title>LoggerSDK Demo</title>
|
|
399
|
-
// </head>
|
|
400
|
-
// <body>
|
|
401
|
-
// <h1>LoggerSDK Demo</h1>
|
|
402
|
-
// <script src="${scriptUrl}"></script>
|
|
403
|
-
// <script>
|
|
404
|
-
// // 通过 UMD 全局 MyLogger 使用
|
|
405
|
-
// const sdk = new MyLogger.LoggerSDK({
|
|
406
|
-
// endpoints: { default: '/api/collect', info: '/api/collect/info', error: '/api/collect/error' },
|
|
407
|
-
// appId: 'demo-app',
|
|
408
|
-
// debug: true,
|
|
409
|
-
// enableAutoPV: true,
|
|
410
|
-
// enablePerf: true
|
|
411
|
-
// });
|
|
412
|
-
// // 手动埋点
|
|
413
|
-
// sdk.track({ type: 'custom', level: 'info', ctx: { action: 'click_demo' } });
|
|
414
|
-
// // 模拟错误
|
|
415
|
-
// setTimeout(() => { throw new Error('demo error'); }, 2000);
|
|
416
|
-
// </script>
|
|
417
|
-
// </body>
|
|
418
|
-
// </html>```;
|
|
419
|
-
// return html;
|
|
420
|
-
// }
|
|
421
153
|
};
|
|
422
154
|
var loggerSDK_default = LoggerSDK;
|
|
423
155
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1,5 +1,51 @@
|
|
|
1
|
-
import { SDKOptions } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
1
|
+
import { SDKOptions } from './types';
|
|
2
|
+
/** 传输选项接口 */
|
|
3
|
+
export interface TransportOptions extends Omit<SDKOptions, 'endpoint'> {
|
|
4
|
+
endpoint: string;
|
|
5
|
+
}
|
|
6
|
+
/** 传输适配器接口 */
|
|
7
|
+
export interface TransportAdapter {
|
|
8
|
+
/** 适配器名称 */
|
|
9
|
+
name: string;
|
|
10
|
+
/** 是否支持当前环境 */
|
|
11
|
+
isSupported(opts?: TransportOptions): boolean;
|
|
12
|
+
/** 发送数据 */
|
|
13
|
+
send(payload: any, opts?: TransportOptions): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Beacon 传输适配器
|
|
17
|
+
* - 兼容性:现代浏览器(Chrome 39+, Firefox 31+, Edge 14+)
|
|
18
|
+
* - 健壮性:页面卸载时可靠传输、不阻塞页面卸载
|
|
19
|
+
* - 适用场景:页面关闭、visibilitychange、pagehide、beforeunload 事件
|
|
20
|
+
* - 限制:无法获取响应、队列有大小限制(通常 64KB)
|
|
21
|
+
*/
|
|
22
|
+
export declare const beaconTransport: TransportAdapter;
|
|
23
|
+
/**
|
|
24
|
+
* 微信小程序传输适配器
|
|
25
|
+
* - 兼容性:微信小程序环境
|
|
26
|
+
* - 健壮性:支持超时控制、完善的错误处理
|
|
27
|
+
* - 适用场景:微信小程序环境下的日志上报
|
|
28
|
+
*/
|
|
29
|
+
export declare const wechatTransport: TransportAdapter;
|
|
30
|
+
/**
|
|
31
|
+
* Image 像素上报适配器
|
|
32
|
+
* - 兼容性:所有浏览器
|
|
33
|
+
* - 健壮性:轻量级、无跨域限制、支持超时控制
|
|
34
|
+
* - 适用场景:数据量小的快速上报、跨域场景、降级方案
|
|
35
|
+
* - 限制:URL 长度限制(默认 1900 字符)
|
|
36
|
+
*/
|
|
37
|
+
export declare const imageTransport: TransportAdapter;
|
|
38
|
+
/**
|
|
39
|
+
* 默认传输函数 - 按环境选择最佳传输方式
|
|
40
|
+
* 浏览器策略:Beacon(可靠) > Image(兼容)
|
|
41
|
+
* 微信小程序策略:WeChat Request
|
|
42
|
+
*/
|
|
43
|
+
export declare function defaultTransport(payload: any, opts?: TransportOptions): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* 导出所有适配器,方便自定义使用
|
|
46
|
+
*/
|
|
47
|
+
export declare const TransportAdapters: {
|
|
48
|
+
beacon: TransportAdapter;
|
|
49
|
+
wechat: TransportAdapter;
|
|
50
|
+
image: TransportAdapter;
|
|
51
|
+
};
|