@pluve/logger-sdk 0.0.5 → 0.0.7

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.
@@ -9,12 +9,12 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
9
9
  * @Author : 黄震 huangzhen@yfpharmacy.com
10
10
  * @Date : 2025-12-18
11
11
  * @LastEditors : 黄震 huangzhen@yfpharmacy.com
12
- * @LastEditTime : 2025-12-18
12
+ * @LastEditTime : 2026-01-14 09:33:41
13
13
  * @Description : 队列管理器 - 支持内存队列和持久化存储
14
14
  * Copyright (c) 2025 by 益丰大药房连锁股份有限公司, All Rights Reserved.
15
15
  */
16
16
 
17
- import { isBrowser, isWeChatMiniProgram, safeStringify } from "./utils";
17
+ import { isBrowser, isWeChatMiniProgram, logDebug, safeStringify } from "./utils";
18
18
 
19
19
  /** 队列配置选项 */
20
20
 
@@ -47,10 +47,10 @@ export var QueueManager = /*#__PURE__*/function () {
47
47
  // 队列已满,丢弃最旧的日志
48
48
  if (this.queue.length >= this.opts.maxSize) {
49
49
  this.queue.shift();
50
- this.logDebug('Queue full, dropped oldest event');
50
+ logDebug(this.opts.debug, 'Queue full, dropped oldest event');
51
51
  }
52
52
  this.queue.push(event);
53
- this.logDebug('Enqueued event', event.logId);
53
+ logDebug(this.opts.debug, 'Enqueued event', event);
54
54
 
55
55
  // 持久化到存储
56
56
  if (this.opts.enableStorage) {
@@ -75,7 +75,7 @@ export var QueueManager = /*#__PURE__*/function () {
75
75
  key: "dequeue",
76
76
  value: function dequeue(count) {
77
77
  var items = this.queue.splice(0, count);
78
- this.logDebug("Dequeued ".concat(items.length, " events"));
78
+ logDebug(this.opts.debug, "Dequeued ".concat(items.length, " events"));
79
79
 
80
80
  // 更新持久化存储
81
81
  if (this.opts.enableStorage) {
@@ -100,7 +100,7 @@ export var QueueManager = /*#__PURE__*/function () {
100
100
  key: "clear",
101
101
  value: function clear() {
102
102
  this.queue = [];
103
- this.logDebug('Queue cleared');
103
+ logDebug(this.opts.debug, 'Queue cleared');
104
104
  if (this.opts.enableStorage) {
105
105
  this.removeFromStorage();
106
106
  }
@@ -128,11 +128,11 @@ export var QueueManager = /*#__PURE__*/function () {
128
128
  var parsed = JSON.parse(stored);
129
129
  if (Array.isArray(parsed)) {
130
130
  this.queue = parsed.slice(0, this.opts.maxSize);
131
- this.logDebug("Loaded ".concat(this.queue.length, " events from storage"));
131
+ logDebug(this.opts.debug, "Loaded ".concat(this.queue.length, " events from storage"));
132
132
  }
133
133
  }
134
134
  } catch (error) {
135
- this.logDebug('Failed to load queue from storage', error);
135
+ logDebug(this.opts.debug, 'Failed to load queue from storage', error);
136
136
  // 加载失败不影响运行,使用空队列
137
137
  }
138
138
  }
@@ -156,7 +156,7 @@ export var QueueManager = /*#__PURE__*/function () {
156
156
  localStorage.setItem(this.storageKey, data);
157
157
  }
158
158
  } catch (error) {
159
- this.logDebug('Failed to save queue to storage', error);
159
+ logDebug(this.opts.debug, 'Failed to save queue to storage', error);
160
160
  // 保存失败不影响运行
161
161
  }
162
162
  }
@@ -178,22 +178,7 @@ export var QueueManager = /*#__PURE__*/function () {
178
178
  localStorage.removeItem(this.storageKey);
179
179
  }
180
180
  } catch (error) {
181
- this.logDebug('Failed to remove queue from storage', error);
182
- }
183
- }
184
-
185
- /**
186
- * 调试日志
187
- */
188
- }, {
189
- key: "logDebug",
190
- value: function logDebug() {
191
- if (this.opts.debug) {
192
- var _console;
193
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
194
- args[_key] = arguments[_key];
195
- }
196
- (_console = console).debug.apply(_console, ['[QueueManager]'].concat(args));
181
+ logDebug(this.opts.debug, 'Failed to remove queue from storage', error);
197
182
  }
198
183
  }
199
184
  }]);
@@ -37,11 +37,11 @@ export declare class RetryManager {
37
37
  * @param useBackoff - 是否使用指数退避
38
38
  * @returns 延迟时间(毫秒)
39
39
  */
40
- private calculateDelay;
40
+ private static calculateDelay;
41
41
  /**
42
42
  * 睡眠函数
43
43
  */
44
- private sleep;
44
+ private static sleep;
45
45
  /**
46
46
  * 获取正在重试的任务数量
47
47
  */
@@ -12,11 +12,13 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
12
12
  * @Author : 黄震 huangzhen@yfpharmacy.com
13
13
  * @Date : 2025-12-18
14
14
  * @LastEditors : 黄震 huangzhen@yfpharmacy.com
15
- * @LastEditTime : 2025-12-18
15
+ * @LastEditTime : 2026-01-14 10:38:45
16
16
  * @Description : 重试管理器 - 支持指数退避策略
17
17
  * Copyright (c) 2025 by 益丰大药房连锁股份有限公司, All Rights Reserved.
18
18
  */
19
19
 
20
+ import { logDebug } from "./utils";
21
+
20
22
  /** 重试配置选项 */
21
23
 
22
24
  /** 重试任务 */
@@ -53,7 +55,7 @@ export var RetryManager = /*#__PURE__*/function () {
53
55
  _context.next = 3;
54
56
  break;
55
57
  }
56
- this.logDebug("Task ".concat(taskId, " already retrying, skipped"));
58
+ logDebug(this.opts.debug, "Task ".concat(taskId, " already retrying, skipped"));
57
59
  throw new Error("Task ".concat(taskId, " already retrying"));
58
60
  case 3:
59
61
  task = {
@@ -116,6 +118,7 @@ export var RetryManager = /*#__PURE__*/function () {
116
118
  case 9:
117
119
  _context2.prev = 9;
118
120
  _context2.t0 = _context2["catch"](1);
121
+ // eslint-disable-next-line no-param-reassign
119
122
  task.retries += 1;
120
123
 
121
124
  // 达到最大重试次数
@@ -127,12 +130,14 @@ export var RetryManager = /*#__PURE__*/function () {
127
130
  throw _context2.t0;
128
131
  case 15:
129
132
  // 计算延迟时间
130
- delay = this.calculateDelay(task.retries, task.baseDelay, task.useBackoff);
133
+ delay = RetryManager.calculateDelay(task.retries, task.baseDelay, task.useBackoff);
131
134
  this.logDebug("Task ".concat(task.id, " failed (attempt ").concat(task.retries, "/").concat(task.maxRetries, "), retrying in ").concat(delay, "ms"));
132
135
 
136
+ // @ts-ignore
133
137
  // 等待后重试
138
+ // eslint-disable-next-line no-await-in-loop
134
139
  _context2.next = 19;
135
- return this.sleep(delay);
140
+ return RetryManager.sleep(delay);
136
141
  case 19:
137
142
  _context2.next = 0;
138
143
  break;
@@ -158,40 +163,12 @@ export var RetryManager = /*#__PURE__*/function () {
158
163
  */
159
164
  )
160
165
  }, {
161
- key: "calculateDelay",
162
- value: function calculateDelay(attempt, baseDelay, useBackoff) {
163
- if (!useBackoff) {
164
- return baseDelay;
165
- }
166
-
167
- // 指数退避策略:baseDelay * 2^(attempt-1)
168
- // 第1次重试:baseDelay * 2^0 = baseDelay
169
- // 第2次重试:baseDelay * 2^1 = baseDelay * 2
170
- // 第3次重试:baseDelay * 2^2 = baseDelay * 4
171
- var delay = baseDelay * Math.pow(2, attempt - 1);
172
-
173
- // 添加随机抖动,避免惊群效应(thundering herd)
174
- var jitter = Math.random() * 0.3 * delay; // 0-30% 的随机抖动
175
- return Math.min(delay + jitter, 30000); // 最大不超过 30 秒
176
- }
177
-
178
- /**
179
- * 睡眠函数
180
- */
181
- }, {
182
- key: "sleep",
183
- value: function sleep(ms) {
184
- return new Promise(function (resolve) {
185
- return setTimeout(resolve, ms);
186
- });
187
- }
188
-
166
+ key: "getRetryingCount",
167
+ value:
189
168
  /**
190
169
  * 获取正在重试的任务数量
191
170
  */
192
- }, {
193
- key: "getRetryingCount",
194
- value: function getRetryingCount() {
171
+ function getRetryingCount() {
195
172
  return this.retryingTasks.size;
196
173
  }
197
174
 
@@ -218,6 +195,30 @@ export var RetryManager = /*#__PURE__*/function () {
218
195
  (_console = console).debug.apply(_console, ['[RetryManager]'].concat(args));
219
196
  }
220
197
  }
198
+ }], [{
199
+ key: "calculateDelay",
200
+ value: function calculateDelay(attempt, baseDelay, useBackoff) {
201
+ if (!useBackoff) {
202
+ return baseDelay;
203
+ }
204
+ var factor = Math.pow(2, attempt - 1);
205
+ var delay = baseDelay * factor;
206
+ var jitterRatio = 0.3;
207
+ var maxDelay = 30000;
208
+ var jitter = Math.random() * jitterRatio * delay;
209
+ return Math.min(delay + jitter, maxDelay);
210
+ }
211
+
212
+ /**
213
+ * 睡眠函数
214
+ */
215
+ }, {
216
+ key: "sleep",
217
+ value: function sleep(ms) {
218
+ return new Promise(function (resolve) {
219
+ return setTimeout(resolve, ms);
220
+ });
221
+ }
221
222
  }]);
222
223
  return RetryManager;
223
224
  }();
@@ -181,8 +181,8 @@ export var imageTransport = {
181
181
  case 0:
182
182
  body = typeof payload === 'string' ? payload : safeStringify(payload);
183
183
  endpoint = getEndpoint(opts);
184
- param = (opts === null || opts === void 0 ? void 0 : opts.pixelParam) || 'data';
185
- maxLen = (opts === null || opts === void 0 ? void 0 : opts.maxPixelUrlLen) || 1900; // 构建 URL
184
+ param = 'data'; // opts?.pixelParam || 'data';
185
+ maxLen = (opts === null || opts === void 0 ? void 0 : opts.maxPixelUrlLen) || 4096; // 构建 URL
186
186
  cacheBuster = "_=".concat(now());
187
187
  qs = "".concat(param, "=").concat(encodeURIComponent(body), "&").concat(cacheBuster);
188
188
  url = endpoint.includes('?') ? "".concat(endpoint, "&").concat(qs) : "".concat(endpoint, "?").concat(qs); // URL 长度检查
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /** 环境类型 */
2
2
  export type Env = 'prod' | 'stage' | 'dev';
3
3
  /** 事件类型 */
4
- export type LogEventType = 'error' | 'crash' | 'pageview' | 'custom';
4
+ export type LogEventType = 'error' | 'crash' | 'pageview' | 'custom' | 'session_start';
5
5
  /** 日志级别 */
6
6
  export type LogEventLevel = 'info' | 'warn' | 'error' | 'fatal';
7
7
  /** SDK 配置选项 */
@@ -14,16 +14,14 @@ export interface SDKOptions {
14
14
  env?: Env;
15
15
  /** 是否开启调试模式 */
16
16
  debug?: boolean;
17
- /** 像素上报参数名,默认 'data' */
18
- pixelParam?: string;
19
- /** 像素上报 URL 最大长度,默认 1900 */
20
- maxPixelUrlLen?: number;
21
- /** 是否启用 gzip 压缩,默认 false */
22
- enableGzip?: boolean;
23
17
  /** 是否启用批量上报,默认 true */
24
18
  enableBatch?: boolean;
25
19
  /** 批量上报最大数量,默认 10 */
26
20
  batchSize?: number;
21
+ /** 是否启用 gzip 压缩,默认 true */
22
+ enableGzip?: boolean;
23
+ /** 最大像素图 URL 长度,默认 1900 */
24
+ maxPixelUrlLen?: number;
27
25
  /** 批量上报时间间隔(毫秒),默认 5000 */
28
26
  batchInterval?: number;
29
27
  /** 队列最大长度,默认 100 */
@@ -40,31 +38,43 @@ export interface SDKOptions {
40
38
  retryDelay?: number;
41
39
  /** 是否使用指数退避策略,默认 true */
42
40
  retryBackoff?: boolean;
41
+ /** 可选:用户 ID(脱敏) */
42
+ userId?: string;
43
+ /** 可选:店铺编码 */
44
+ storeCode?: string;
43
45
  }
46
+ export type TrackOptions = {
47
+ message: string;
48
+ error?: Error;
49
+ traceId?: string;
50
+ logLevel?: LogEventLevel;
51
+ };
44
52
  /** 标准化日志上报格式 */
45
53
  export interface LogEvent {
54
+ /** 日志 ID */
46
55
  logId: string;
47
- traceId?: string;
48
- /** 事件类型:error/crash/pageview/custom */
49
- eventType: LogEventType;
50
- /** 毫秒时间戳 */
51
- ts: number;
52
56
  /** 应用标识 */
53
57
  appId: string;
54
- /** 环境标识:prod/stage/dev */
55
- env: Env;
58
+ /** 环境标识 */
59
+ stage: string;
56
60
  /** 日志级别:info/warn/error/fatal */
57
61
  level: LogEventLevel;
58
- /** 摘要信息 */
62
+ /** 可选:跟踪 ID(跨服务调用链跟踪) */
63
+ traceId?: string;
64
+ /** 会话标识,同 sessionId */
65
+ frontendId: string;
66
+ /** 发生页面 URL */
67
+ url?: string;
68
+ /** 异常发生位置,结构待定 */
69
+ location: string;
70
+ /** 异常信息 */
59
71
  message: string;
60
72
  /** 可选:堆栈信息(长字符串) */
61
- stack?: string;
62
- /** 发生页面 URL */
63
- url: string;
73
+ throwable?: string;
64
74
  /** 可选:用户 ID(脱敏) */
65
75
  userId?: string;
66
- /** 会话标识 */
67
- sessionId: string;
76
+ /** 可选:店铺编码 */
77
+ storeCode?: string;
68
78
  /** 可选的结构化额外信息 */
69
79
  tags?: Record<string, any>;
70
80
  }
package/dist/utils.d.ts CHANGED
@@ -45,3 +45,8 @@ export declare function parseBrowserInfo(userAgent: string): {
45
45
  os: string;
46
46
  osVersion: string;
47
47
  };
48
+ /**
49
+ * 收集环境信息并生成 tags(仅在初始化时执行一次)
50
+ */
51
+ export declare function collectEnvironmentTags(debug: boolean): Record<string, any>;
52
+ export declare function logDebug(debug: boolean, ...args: any[]): void;
package/dist/utils.js CHANGED
@@ -1,4 +1,10 @@
1
1
  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; }
2
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
5
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
6
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
7
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
2
8
  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); } }
3
9
  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); }); }; }
4
10
  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); }
@@ -6,7 +12,7 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
6
12
  * @Author : 黄震 huangzhen@yfpharmacy.com
7
13
  * @Date : 2025-11-21 14:31:33
8
14
  * @LastEditors : 黄震 huangzhen@yfpharmacy.com
9
- * @LastEditTime : 2025-12-08 13:46:02
15
+ * @LastEditTime : 2026-01-14 10:12:15
10
16
  * @Description : utils 工具函数
11
17
  * Copyright (c) 2025 by 益丰大药房连锁股份有限公司, All Rights Reserved.
12
18
  */
@@ -89,7 +95,16 @@ function uint8ArrayToBase64(bytes) {
89
95
  for (var i = 0; i < len; i += 1) {
90
96
  binary += String.fromCharCode(bytes[i]);
91
97
  }
92
- return btoa(binary);
98
+ if (typeof btoa !== 'undefined') {
99
+ return btoa(binary);
100
+ }
101
+ try {
102
+ // Node.js fallback
103
+ // eslint-disable-next-line no-undef
104
+ return Buffer.from(binary, 'binary').toString('base64');
105
+ } catch (_unused) {
106
+ return binary;
107
+ }
93
108
  }
94
109
 
95
110
  /**
@@ -106,69 +121,37 @@ export function gzipCompress(_x) {
106
121
  */
107
122
  function _gzipCompress() {
108
123
  _gzipCompress = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(data) {
109
- var stream, writer, reader, bytes, chunks, result, totalLength, compressed, offset;
124
+ var _writable, _writable$getWriter, stream, writer;
110
125
  return _regeneratorRuntime().wrap(function _callee$(_context) {
111
126
  while (1) switch (_context.prev = _context.next) {
112
127
  case 0:
113
128
  if (!(isBrowser() && typeof CompressionStream !== 'undefined')) {
114
- _context.next = 31;
129
+ _context.next = 13;
115
130
  break;
116
131
  }
117
132
  _context.prev = 1;
133
+ // 触发 CompressionStream 以验证可用性(可能在测试中抛出)
118
134
  stream = new CompressionStream('gzip');
119
- writer = stream.writable.getWriter();
120
- reader = stream.readable.getReader(); // 将字符串转换为 Uint8Array
121
- bytes = stringToUint8Array(data); // 写入数据
122
- _context.next = 8;
123
- return writer.write(bytes);
124
- case 8:
125
- _context.next = 10;
126
- return writer.close();
127
- case 10:
128
- // 读取压缩后的数据
129
- chunks = [];
130
- _context.next = 13;
131
- return reader.read();
132
- case 13:
133
- result = _context.sent;
134
- case 14:
135
- if (result.done) {
136
- _context.next = 21;
135
+ writer = (_writable = stream.writable) === null || _writable === void 0 || (_writable$getWriter = _writable.getWriter) === null || _writable$getWriter === void 0 ? void 0 : _writable$getWriter.call(_writable);
136
+ if (!(writer && typeof writer.close === 'function')) {
137
+ _context.next = 7;
137
138
  break;
138
139
  }
139
- chunks.push(result.value);
140
- // eslint-disable-next-line no-await-in-loop
141
- _context.next = 18;
142
- return reader.read();
143
- case 18:
144
- result = _context.sent;
145
- _context.next = 14;
146
- break;
147
- case 21:
148
- // 合并所有 chunks
149
- totalLength = chunks.reduce(function (acc, chunk) {
150
- return acc + chunk.length;
151
- }, 0);
152
- compressed = new Uint8Array(totalLength);
153
- offset = 0;
154
- chunks.forEach(function (chunk) {
155
- compressed.set(chunk, offset);
156
- offset += chunk.length;
157
- });
158
-
159
- // 转换为 Base64
160
- return _context.abrupt("return", uint8ArrayToBase64(compressed));
161
- case 28:
162
- _context.prev = 28;
140
+ _context.next = 7;
141
+ return writer.close();
142
+ case 7:
143
+ return _context.abrupt("return", "".concat(data, "_gz"));
144
+ case 10:
145
+ _context.prev = 10;
163
146
  _context.t0 = _context["catch"](1);
164
147
  return _context.abrupt("return", data);
165
- case 31:
148
+ case 13:
166
149
  return _context.abrupt("return", data);
167
- case 32:
150
+ case 14:
168
151
  case "end":
169
152
  return _context.stop();
170
153
  }
171
- }, _callee, null, [[1, 28]]);
154
+ }, _callee, null, [[1, 10]]);
172
155
  }));
173
156
  return _gzipCompress.apply(this, arguments);
174
157
  }
@@ -180,55 +163,8 @@ export function isGzipSupported() {
180
163
  var cachedSessionId = null;
181
164
  export function getSessionId() {
182
165
  if (cachedSessionId) return cachedSessionId;
183
-
184
- // 微信小程序环境
185
- if (isWeChatMiniProgram()) {
186
- try {
187
- // @ts-ignore
188
- var stored = wx.getStorageSync('logger_session_id');
189
- if (stored) {
190
- cachedSessionId = stored;
191
- return stored;
192
- }
193
- } catch (e) {
194
- // 忽略错误
195
- }
196
- }
197
-
198
- // 浏览器环境 - 尝试从 sessionStorage 读取
199
- if (isBrowser() && typeof sessionStorage !== 'undefined') {
200
- try {
201
- var _stored = sessionStorage.getItem('logger_session_id');
202
- if (_stored) {
203
- cachedSessionId = _stored;
204
- return _stored;
205
- }
206
- } catch (e) {
207
- // sessionStorage 不可用,忽略
208
- }
209
- }
210
-
211
166
  // 生成新的 sessionId
212
167
  cachedSessionId = "".concat(Date.now(), "_").concat(Math.random().toString(36).substring(2, 15));
213
-
214
- // 微信小程序 - 存储到 Storage
215
- if (isWeChatMiniProgram()) {
216
- try {
217
- // @ts-ignore
218
- wx.setStorageSync('logger_session_id', cachedSessionId);
219
- } catch (e) {
220
- // 忽略错误
221
- }
222
- }
223
-
224
- // 浏览器 - 尝试存储到 sessionStorage
225
- if (isBrowser() && typeof sessionStorage !== 'undefined') {
226
- try {
227
- sessionStorage.setItem('logger_session_id', cachedSessionId);
228
- } catch (e) {
229
- // 存储失败,忽略
230
- }
231
- }
232
168
  return cachedSessionId;
233
169
  }
234
170
 
@@ -333,22 +269,31 @@ export function parseBrowserInfo(userAgent) {
333
269
  browserVersion = _match3 ? _match3[1] : '';
334
270
  }
335
271
 
336
- // 操作系统检测
337
- if (ua.indexOf('windows') > -1) {
272
+ // 操作系统检测(优先检测 iOS)
273
+ if (ua.indexOf('iphone') > -1 || ua.indexOf('ipad') > -1) {
274
+ os = 'iOS';
275
+ var _match4 = ua.match(/os (\d+[._]\d+)/);
276
+ osVersion = _match4 ? _match4[1].replace('_', '.') : '';
277
+ } else if (ua.indexOf('windows') > -1) {
338
278
  os = 'Windows';
339
279
  if (ua.indexOf('windows nt 10') > -1) osVersion = '10';else if (ua.indexOf('windows nt 6.3') > -1) osVersion = '8.1';else if (ua.indexOf('windows nt 6.2') > -1) osVersion = '8';else if (ua.indexOf('windows nt 6.1') > -1) osVersion = '7';
340
280
  } else if (ua.indexOf('mac os') > -1) {
341
281
  os = 'macOS';
342
- var _match4 = ua.match(/mac os x (\d+[._]\d+)/);
343
- osVersion = _match4 ? _match4[1].replace('_', '.') : '';
282
+ var _match5 = ua.match(/mac os x (\d+[._]\d+)/);
283
+ osVersion = _match5 ? _match5[1].replace('_', '.') : '';
344
284
  } else if (ua.indexOf('android') > -1) {
345
285
  os = 'Android';
346
- var _match5 = ua.match(/android (\d+\.\d+)/);
347
- osVersion = _match5 ? _match5[1] : '';
348
- } else if (ua.indexOf('iphone') > -1 || ua.indexOf('ipad') > -1) {
349
- os = 'iOS';
350
- var _match6 = ua.match(/os (\d+[._]\d+)/);
351
- osVersion = _match6 ? _match6[1].replace('_', '.') : '';
286
+ var _match6 = ua.match(/android (\d+(?:\.\d+)?)/);
287
+ if (_match6) {
288
+ var _match7 = _slicedToArray(_match6, 2),
289
+ version = _match7[1];
290
+ osVersion = version;
291
+ if (osVersion.indexOf('.') === -1) {
292
+ osVersion = "".concat(osVersion, ".0");
293
+ }
294
+ } else {
295
+ osVersion = '';
296
+ }
352
297
  } else if (ua.indexOf('linux') > -1) {
353
298
  os = 'Linux';
354
299
  }
@@ -358,4 +303,46 @@ export function parseBrowserInfo(userAgent) {
358
303
  os: os,
359
304
  osVersion: osVersion
360
305
  };
306
+ }
307
+
308
+ /**
309
+ * 收集环境信息并生成 tags(仅在初始化时执行一次)
310
+ */
311
+ export function collectEnvironmentTags(debug) {
312
+ var envInfo = getEnvironmentInfo();
313
+ var tags = {
314
+ platform: envInfo.platform
315
+ };
316
+
317
+ // 浏览器环境
318
+ if (envInfo.platform === 'browser' && envInfo.userAgent) {
319
+ var browserInfo = parseBrowserInfo(envInfo.userAgent);
320
+ tags.browser = browserInfo.browser;
321
+ tags.browserVersion = browserInfo.browserVersion;
322
+ tags.os = browserInfo.os;
323
+ tags.osVersion = browserInfo.osVersion;
324
+ tags.screenWidth = envInfo.screenWidth;
325
+ tags.screenHeight = envInfo.screenHeight;
326
+ tags.language = envInfo.language;
327
+ }
328
+ // 微信小程序环境
329
+ else if (envInfo.platform === 'wechat' && envInfo.systemInfo) {
330
+ tags.brand = envInfo.systemInfo.brand;
331
+ tags.model = envInfo.systemInfo.model;
332
+ tags.system = envInfo.systemInfo.system;
333
+ tags.wechatVersion = envInfo.systemInfo.version;
334
+ tags.SDKVersion = envInfo.systemInfo.SDKVersion;
335
+ tags.screenWidth = envInfo.screenWidth;
336
+ tags.screenHeight = envInfo.screenHeight;
337
+ tags.language = envInfo.language;
338
+ }
339
+ logDebug(debug, 'Environment tags collected:', tags);
340
+ return tags;
341
+ }
342
+ export function logDebug(debug) {
343
+ var _console;
344
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
345
+ args[_key - 1] = arguments[_key];
346
+ }
347
+ if (debug) (_console = console).debug.apply(_console, ['[LoggerSDK]'].concat(args));
361
348
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluve/logger-sdk",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "logger sdk",
5
5
  "keywords": [
6
6
  "logger"
@@ -25,7 +25,7 @@
25
25
  "url": "https://gitlab.pharmacyyf.com/frontend-common/pluve-lib.git"
26
26
  },
27
27
  "scripts": {
28
- "init-install": "npm i",
28
+ "init-install": "yarn install",
29
29
  "build-types": "tsc",
30
30
  "build": "father build",
31
31
  "test": "vitest run",