@pluve/logger-sdk 0.0.1 → 0.0.3

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 (44) hide show
  1. package/README.md +195 -76
  2. package/dist/index.js +9 -0
  3. package/dist/loggerSDK.d.ts +36 -0
  4. package/dist/{esm/dbQueue.js → loggerSDK.js} +195 -161
  5. package/dist/transportAdapter.d.ts +51 -0
  6. package/dist/{esm/transportAdapter.js → transportAdapter.js} +260 -111
  7. package/dist/types.d.ts +46 -0
  8. package/dist/utils.d.ts +30 -0
  9. package/dist/utils.js +229 -0
  10. package/lib/dbQueue.js +133 -0
  11. package/{dist/esm → lib}/index.js +1 -1
  12. package/lib/loggerSDK.js +571 -0
  13. package/lib/storeAdapter.js +99 -0
  14. package/lib/transportAdapter.d.ts +66 -0
  15. package/lib/transportAdapter.js +406 -0
  16. package/lib/types.js +1 -0
  17. package/lib/utils.js +50 -0
  18. package/package.json +8 -2
  19. package/dist/cjs/dbQueue.js +0 -88
  20. package/dist/cjs/index.js +0 -29
  21. package/dist/cjs/loggerSDK.js +0 -426
  22. package/dist/cjs/storeAdapter.js +0 -64
  23. package/dist/cjs/transportAdapter.d.ts +0 -5
  24. package/dist/cjs/transportAdapter.js +0 -109
  25. package/dist/cjs/types.js +0 -17
  26. package/dist/cjs/utils.js +0 -69
  27. package/dist/esm/dbQueue.d.ts +0 -10
  28. package/dist/esm/loggerSDK.d.ts +0 -29
  29. package/dist/esm/loggerSDK.js +0 -761
  30. package/dist/esm/storeAdapter.d.ts +0 -7
  31. package/dist/esm/storeAdapter.js +0 -139
  32. package/dist/esm/transportAdapter.d.ts +0 -5
  33. package/dist/esm/types.d.ts +0 -35
  34. package/dist/esm/utils.d.ts +0 -5
  35. package/dist/esm/utils.js +0 -53
  36. package/dist/umd/logger-sdk.min.js +0 -1
  37. /package/dist/{cjs/index.d.ts → index.d.ts} +0 -0
  38. /package/dist/{esm/types.js → types.js} +0 -0
  39. /package/{dist/cjs → lib}/dbQueue.d.ts +0 -0
  40. /package/{dist/esm → lib}/index.d.ts +0 -0
  41. /package/{dist/cjs → lib}/loggerSDK.d.ts +0 -0
  42. /package/{dist/cjs → lib}/storeAdapter.d.ts +0 -0
  43. /package/{dist/cjs → lib}/types.d.ts +0 -0
  44. /package/{dist/cjs → lib}/utils.d.ts +0 -0
@@ -1,142 +1,291 @@
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
2
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
- 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; }
4
- 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; }
5
- 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; }
6
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
- 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); }
8
3
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
9
4
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
10
5
  /*
11
6
  * @Author : 黄震 huangzhen@yfpharmacy.com
12
7
  * @Date : 2025-11-21 14:35:48
13
8
  * @LastEditors : 黄震 huangzhen@yfpharmacy.com
14
- * @LastEditTime : 2025-12-02 15:18:05
15
- * @Description : 传输适配器接口,用于发送日志到服务器
9
+ * @LastEditTime : 2025-12-04 14:30:00
10
+ * @Description : 传输适配器 - Beacon、像素图和微信小程序方式
16
11
  * Copyright (c) 2025 by 益丰大药房连锁股份有限公司, All Rights Reserved.
17
12
  */
18
13
 
19
- import { isWeChatMiniProgram, safeStringify, isBrowser, now } from "./utils";
14
+ import { safeStringify, isBrowser, isWeChatMiniProgram, now } from "./utils";
15
+
16
+ /** 传输选项接口 */
17
+
18
+ /** 传输适配器接口 */
19
+
20
+ // ==================== 辅助函数 ====================
21
+
22
+ /** 获取端点 URL */
23
+ function getEndpoint(opts) {
24
+ return (opts === null || opts === void 0 ? void 0 : opts.endpoint) || '';
25
+ }
26
+
27
+ // ==================== 1. Beacon 传输适配器(页面卸载场景首选)====================
28
+
29
+ /**
30
+ * Beacon 传输适配器
31
+ * - 兼容性:现代浏览器(Chrome 39+, Firefox 31+, Edge 14+)
32
+ * - 健壮性:页面卸载时可靠传输、不阻塞页面卸载
33
+ * - 适用场景:页面关闭、visibilitychange、pagehide、beforeunload 事件
34
+ * - 限制:无法获取响应、队列有大小限制(通常 64KB)
35
+ */
36
+ export var beaconTransport = {
37
+ name: 'beacon',
38
+ isSupported: function isSupported() {
39
+ return isBrowser() && typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function';
40
+ },
41
+ send: function send(payload, opts) {
42
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
43
+ var body, endpoint, blob, success;
44
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
45
+ while (1) switch (_context.prev = _context.next) {
46
+ case 0:
47
+ body = typeof payload === 'string' ? payload : safeStringify(payload);
48
+ endpoint = getEndpoint(opts); // sendBeacon 使用 Blob 确保正确的 Content-Type
49
+ blob = new Blob([body], {
50
+ type: 'application/json'
51
+ });
52
+ success = navigator.sendBeacon(endpoint, blob);
53
+ if (success) {
54
+ _context.next = 6;
55
+ break;
56
+ }
57
+ throw new Error('sendBeacon failed (queue full or other error)');
58
+ case 6:
59
+ case "end":
60
+ return _context.stop();
61
+ }
62
+ }, _callee);
63
+ }))();
64
+ }
65
+ };
66
+
67
+ // ==================== 2. 微信小程序传输适配器(微信环境专用)====================
68
+
69
+ /**
70
+ * 微信小程序传输适配器
71
+ * - 兼容性:微信小程序环境
72
+ * - 健壮性:支持超时控制、完善的错误处理
73
+ * - 适用场景:微信小程序环境下的日志上报
74
+ */
75
+ export var wechatTransport = {
76
+ name: 'wechat',
77
+ isSupported: function isSupported() {
78
+ return isWeChatMiniProgram();
79
+ },
80
+ send: function send(payload, opts) {
81
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
82
+ var body, endpoint, timeout;
83
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
84
+ while (1) switch (_context2.prev = _context2.next) {
85
+ case 0:
86
+ body = typeof payload === 'string' ? payload : safeStringify(payload);
87
+ endpoint = getEndpoint(opts);
88
+ timeout = 10000; // 10秒超时
89
+ return _context2.abrupt("return", new Promise(function (resolve, reject) {
90
+ var timeoutId = null;
91
+ var settled = false;
92
+
93
+ // 超时处理
94
+ timeoutId = setTimeout(function () {
95
+ if (!settled) {
96
+ settled = true;
97
+ reject(new Error("WeChat request timeout after ".concat(timeout, "ms")));
98
+ }
99
+ }, timeout);
100
+
101
+ // @ts-ignore
102
+ wx.request({
103
+ url: endpoint,
104
+ method: 'POST',
105
+ data: body,
106
+ header: {
107
+ 'Content-Type': 'application/json'
108
+ },
109
+ success: function success(res) {
110
+ if (timeoutId) clearTimeout(timeoutId);
111
+ if (!settled) {
112
+ settled = true;
113
+ if (res.statusCode >= 200 && res.statusCode < 300) {
114
+ resolve();
115
+ } else {
116
+ reject(new Error("HTTP ".concat(res.statusCode)));
117
+ }
118
+ }
119
+ },
120
+ fail: function fail(err) {
121
+ if (timeoutId) clearTimeout(timeoutId);
122
+ if (!settled) {
123
+ settled = true;
124
+ reject(new Error("WeChat request failed: ".concat(err.errMsg || 'unknown error')));
125
+ }
126
+ }
127
+ });
128
+ }));
129
+ case 4:
130
+ case "end":
131
+ return _context2.stop();
132
+ }
133
+ }, _callee2);
134
+ }))();
135
+ }
136
+ };
137
+
138
+ // ==================== 3. Image 像素上报适配器(兼容性最好)====================
139
+
140
+ /**
141
+ * Image 像素上报适配器
142
+ * - 兼容性:所有浏览器
143
+ * - 健壮性:轻量级、无跨域限制、支持超时控制
144
+ * - 适用场景:数据量小的快速上报、跨域场景、降级方案
145
+ * - 限制:URL 长度限制(默认 1900 字符)
146
+ */
147
+ export var imageTransport = {
148
+ name: 'image',
149
+ isSupported: function isSupported() {
150
+ return isBrowser() && typeof Image !== 'undefined';
151
+ },
152
+ send: function send(payload, opts) {
153
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
154
+ var body, endpoint, param, maxLen, cacheBuster, qs, url;
155
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
156
+ while (1) switch (_context3.prev = _context3.next) {
157
+ case 0:
158
+ body = typeof payload === 'string' ? payload : safeStringify(payload);
159
+ endpoint = getEndpoint(opts);
160
+ param = (opts === null || opts === void 0 ? void 0 : opts.pixelParam) || 'data';
161
+ maxLen = (opts === null || opts === void 0 ? void 0 : opts.maxPixelUrlLen) || 1900; // 构建 URL
162
+ cacheBuster = "_=".concat(now());
163
+ qs = "".concat(param, "=").concat(encodeURIComponent(body), "&").concat(cacheBuster);
164
+ url = endpoint.includes('?') ? "".concat(endpoint, "&").concat(qs) : "".concat(endpoint, "?").concat(qs); // URL 长度检查
165
+ if (!(url.length > maxLen)) {
166
+ _context3.next = 9;
167
+ break;
168
+ }
169
+ throw new Error("URL too long (".concat(url.length, " > ").concat(maxLen, ")"));
170
+ case 9:
171
+ return _context3.abrupt("return", new Promise(function (resolve, reject) {
172
+ var img = new Image();
173
+ var timeoutId = null;
174
+ var settled = false;
175
+
176
+ // 超时处理(5秒)
177
+ timeoutId = setTimeout(function () {
178
+ if (!settled) {
179
+ settled = true;
180
+ img.src = ''; // 取消请求
181
+ reject(new Error('Image request timeout after 5000ms'));
182
+ }
183
+ }, 5000);
184
+ img.onload = function () {
185
+ if (timeoutId) clearTimeout(timeoutId);
186
+ if (!settled) {
187
+ settled = true;
188
+ resolve();
189
+ }
190
+ };
191
+ img.onerror = function () {
192
+ if (timeoutId) clearTimeout(timeoutId);
193
+ if (!settled) {
194
+ settled = true;
195
+ reject(new Error('Image request failed'));
196
+ }
197
+ };
198
+
199
+ // 发起请求
200
+ img.src = url;
201
+ }));
202
+ case 10:
203
+ case "end":
204
+ return _context3.stop();
205
+ }
206
+ }, _callee3);
207
+ }))();
208
+ }
209
+ };
210
+
211
+ // ==================== 默认传输策略 ====================
212
+
213
+ /**
214
+ * 默认传输函数 - 按环境选择最佳传输方式
215
+ * 浏览器策略:Beacon(可靠) > Image(兼容)
216
+ * 微信小程序策略:WeChat Request
217
+ */
20
218
  export function defaultTransport(_x, _x2) {
21
219
  return _defaultTransport.apply(this, arguments);
22
220
  }
221
+
222
+ /**
223
+ * 导出所有适配器,方便自定义使用
224
+ */
23
225
  function _defaultTransport() {
24
- _defaultTransport = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(payload, opts) {
25
- var _endpoints;
26
- var body, timeout, endpoint, blob, ok, param, cacheBuster, urlBase, qs, url, maxLen, img, controller;
27
- return _regeneratorRuntime().wrap(function _callee$(_context) {
28
- while (1) switch (_context.prev = _context.next) {
226
+ _defaultTransport = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(payload, opts) {
227
+ var transports, adapter;
228
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
229
+ while (1) switch (_context4.prev = _context4.next) {
29
230
  case 0:
30
- body = typeof payload === 'string' ? payload : safeStringify(payload);
31
- timeout = (opts === null || opts === void 0 ? void 0 : opts.timeout) || 10000;
32
- endpoint = opts && opts.endpoint ? opts.endpoint : ((_endpoints = opts.endpoints) === null || _endpoints === void 0 ? void 0 : _endpoints.default) || '';
33
- if (!(isBrowser() && typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function' && opts !== null && opts !== void 0 && opts.useBeacon)) {
34
- _context.next = 9;
35
- break;
36
- }
37
- blob = new Blob([body], {
38
- type: 'application/json'
39
- });
40
- ok = navigator.sendBeacon(endpoint || '', blob);
41
- if (!ok) {
42
- _context.next = 8;
43
- break;
44
- }
45
- return _context.abrupt("return", Promise.resolve());
46
- case 8:
47
- return _context.abrupt("return", Promise.reject(new Error('sendBeacon failed')));
48
- case 9:
49
231
  if (!isWeChatMiniProgram()) {
50
- _context.next = 11;
232
+ _context4.next = 5;
51
233
  break;
52
234
  }
53
- return _context.abrupt("return", new Promise(function (resolve, reject) {
54
- var timer = null;
55
- // @ts-ignore
56
- wx.request({
57
- url: endpoint || '',
58
- method: 'POST',
59
- data: body,
60
- header: _objectSpread({
61
- 'Content-Type': 'application/json'
62
- }, opts && opts.globalHeaders ? opts.globalHeaders : {}),
63
- success: function success() {
64
- if (timer) clearTimeout(timer);
65
- resolve();
66
- },
67
- fail: function fail(err) {
68
- if (timer) clearTimeout(timer);
69
- reject(err);
70
- }
71
- });
72
- timer = setTimeout(function () {
73
- return reject(new Error('timeout'));
74
- }, timeout);
75
- }));
76
- case 11:
77
- if (!(isBrowser() && opts !== null && opts !== void 0 && opts.usePixel)) {
78
- _context.next = 23;
235
+ if (!wechatTransport.isSupported(opts)) {
236
+ _context4.next = 5;
79
237
  break;
80
238
  }
81
- param = (opts === null || opts === void 0 ? void 0 : opts.pixelParam) || 'data';
82
- cacheBuster = "_=".concat(now());
83
- urlBase = endpoint || '';
84
- qs = "".concat(param, "=").concat(encodeURIComponent(body), "&").concat(cacheBuster);
85
- url = urlBase.includes('?') ? "".concat(urlBase, "&").concat(qs) : "".concat(urlBase, "?").concat(qs);
86
- maxLen = (opts === null || opts === void 0 ? void 0 : opts.maxPixelUrlLen) || 1900;
87
- if (!(url.length > maxLen)) {
88
- _context.next = 21;
239
+ _context4.next = 4;
240
+ return wechatTransport.send(payload, opts);
241
+ case 4:
242
+ return _context4.abrupt("return");
243
+ case 5:
244
+ // 浏览器环境使用 Beacon Image
245
+ transports = [beaconTransport, imageTransport]; // 尝试找到第一个支持的适配器
246
+ adapter = transports.find(function (t) {
247
+ return t.isSupported(opts);
248
+ });
249
+ if (adapter) {
250
+ _context4.next = 9;
89
251
  break;
90
252
  }
91
- _context.next = 23;
253
+ throw new Error('No supported transport adapter available');
254
+ case 9:
255
+ _context4.prev = 9;
256
+ _context4.next = 12;
257
+ return adapter.send(payload, opts);
258
+ case 12:
259
+ _context4.next = 27;
92
260
  break;
93
- case 21:
94
- // 使用 Image 像素上报
95
- img = new Image();
96
- return _context.abrupt("return", new Promise(function (resolve, reject) {
97
- var timer = null;
98
- img.onload = function () {
99
- if (timer) clearTimeout(timer);
100
- resolve();
101
- };
102
- img.onerror = function () {
103
- if (timer) clearTimeout(timer);
104
- reject(new Error('pixel error'));
105
- };
106
- timer = setTimeout(function () {
107
- return reject(new Error('timeout'));
108
- }, timeout);
109
- img.src = url;
110
- }));
111
- case 23:
112
- if (!(typeof fetch === 'function')) {
113
- _context.next = 27;
261
+ case 14:
262
+ _context4.prev = 14;
263
+ _context4.t0 = _context4["catch"](9);
264
+ if (!(adapter.name === 'beacon' && imageTransport.isSupported(opts))) {
265
+ _context4.next = 26;
114
266
  break;
115
267
  }
116
- controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
117
- if (controller) setTimeout(function () {
118
- return controller.abort();
119
- }, timeout);
120
- return _context.abrupt("return", fetch(endpoint || '', {
121
- method: 'POST',
122
- headers: _objectSpread(_objectSpread({
123
- 'Content-Type': 'application/json'
124
- }, opts && opts.globalHeaders ? opts.globalHeaders : {}), opts && opts.headers ? opts.headers : {}),
125
- body: body,
126
- // 在页面关闭场景提供尽力传输能力(非标准环境忽略)
127
- // @ts-ignore
128
- keepalive: opts !== null && opts !== void 0 && opts.useBeacon ? true : undefined,
129
- signal: controller ? controller.signal : undefined
130
- }).then(function (res) {
131
- if (!res.ok) throw new Error('network response not ok');
132
- }));
268
+ _context4.prev = 17;
269
+ _context4.next = 20;
270
+ return imageTransport.send(payload, opts);
271
+ case 20:
272
+ return _context4.abrupt("return");
273
+ case 23:
274
+ _context4.prev = 23;
275
+ _context4.t1 = _context4["catch"](17);
276
+ throw _context4.t0;
277
+ case 26:
278
+ throw _context4.t0;
133
279
  case 27:
134
- return _context.abrupt("return", Promise.reject(new Error('no transport available')));
135
- case 28:
136
280
  case "end":
137
- return _context.stop();
281
+ return _context4.stop();
138
282
  }
139
- }, _callee);
283
+ }, _callee4, null, [[9, 14], [17, 23]]);
140
284
  }));
141
285
  return _defaultTransport.apply(this, arguments);
142
- }
286
+ }
287
+ export var TransportAdapters = {
288
+ beacon: beaconTransport,
289
+ wechat: wechatTransport,
290
+ image: imageTransport
291
+ };
@@ -0,0 +1,46 @@
1
+ /** 环境类型 */
2
+ export type Env = 'prod' | 'stage' | 'dev';
3
+ /** 事件类型 */
4
+ export type LogEventType = 'error' | 'crash' | 'pageview' | 'custom';
5
+ /** 日志级别 */
6
+ export type LogEventLevel = 'info' | 'warn' | 'error' | 'fatal';
7
+ /** SDK 配置选项 */
8
+ export interface SDKOptions {
9
+ /** 上报端点 URL */
10
+ endpoint: string;
11
+ /** 应用 ID */
12
+ appId?: string;
13
+ /** 环境标识 */
14
+ env?: Env;
15
+ /** 是否开启调试模式 */
16
+ debug?: boolean;
17
+ /** 像素上报参数名,默认 'data' */
18
+ pixelParam?: string;
19
+ /** 像素上报 URL 最大长度,默认 1900 */
20
+ maxPixelUrlLen?: number;
21
+ }
22
+ /** 标准化日志上报格式 */
23
+ export interface LogEvent {
24
+ /** 事件类型:error/crash/pageview/custom */
25
+ eventType: LogEventType;
26
+ /** 毫秒时间戳 */
27
+ ts: number;
28
+ /** 应用标识 */
29
+ appId: string;
30
+ /** 环境标识:prod/stage/dev */
31
+ env: Env;
32
+ /** 日志级别:info/warn/error/fatal */
33
+ level: LogEventLevel;
34
+ /** 摘要信息 */
35
+ message: string;
36
+ /** 可选:堆栈信息(长字符串) */
37
+ stack?: string;
38
+ /** 发生页面 URL */
39
+ url: string;
40
+ /** 可选:用户 ID(脱敏) */
41
+ userId?: string;
42
+ /** 会话标识 */
43
+ sessionId: string;
44
+ /** 可选的结构化额外信息 */
45
+ tags?: Record<string, any>;
46
+ }
@@ -0,0 +1,30 @@
1
+ export declare const now: () => number;
2
+ export declare function isBrowser(): boolean;
3
+ export declare function isWeChatMiniProgram(): boolean;
4
+ export declare function safeStringify(obj: any): string;
5
+ export declare function getSessionId(): string;
6
+ export declare function getCurrentUrl(): string;
7
+ /** 平台类型 */
8
+ export type PlatformType = 'browser' | 'wechat' | 'unknown';
9
+ /** 环境信息 */
10
+ export interface EnvironmentInfo {
11
+ platform: PlatformType;
12
+ userAgent?: string;
13
+ screenWidth?: number;
14
+ screenHeight?: number;
15
+ language?: string;
16
+ systemInfo?: any;
17
+ }
18
+ /**
19
+ * 获取环境信息
20
+ */
21
+ export declare function getEnvironmentInfo(): EnvironmentInfo;
22
+ /**
23
+ * 解析浏览器信息
24
+ */
25
+ export declare function parseBrowserInfo(userAgent: string): {
26
+ browser: string;
27
+ browserVersion: string;
28
+ os: string;
29
+ osVersion: string;
30
+ };