@pluve/logger-sdk 0.0.7 → 0.0.9

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 (100) hide show
  1. package/README.html +681 -0
  2. package/README.md +131 -153
  3. package/dist/cjs/capture/jsError.js +48 -0
  4. package/dist/cjs/capture/promiseError.js +49 -0
  5. package/dist/cjs/capture/resourceError.js +48 -0
  6. package/dist/cjs/capture/wechatError.js +95 -0
  7. package/dist/cjs/compress/compression.js +84 -0
  8. package/dist/cjs/config/index.js +55 -0
  9. package/dist/cjs/core/fingerprint.js +36 -0
  10. package/dist/cjs/core/httpClient.js +96 -0
  11. package/dist/cjs/core/loggerSDK.js +641 -0
  12. package/dist/cjs/core/queueManager.js +249 -0
  13. package/dist/cjs/core/retryManager.js +127 -0
  14. package/dist/cjs/index.js +29 -0
  15. package/dist/cjs/stack/stacktrace.js +48 -0
  16. package/dist/cjs/transport/beaconTransport.js +64 -0
  17. package/dist/cjs/transport/pixelImageTransport.js +100 -0
  18. package/dist/cjs/transport/transport.js +17 -0
  19. package/dist/cjs/transport/transportAdapter.js +56 -0
  20. package/dist/cjs/transport/wechatTransport.js +103 -0
  21. package/dist/cjs/types/api.js +17 -0
  22. package/dist/cjs/types/env.js +17 -0
  23. package/dist/cjs/types/external.d.ts +21 -0
  24. package/dist/cjs/types/logEvent.js +17 -0
  25. package/dist/cjs/types/logEventLevel.js +17 -0
  26. package/dist/cjs/types/sdkOptions.js +17 -0
  27. package/dist/cjs/types/trackOptions.js +17 -0
  28. package/dist/cjs/utils/environment.js +183 -0
  29. package/dist/cjs/utils/session.js +31 -0
  30. package/dist/cjs/utils/tools.js +82 -0
  31. package/dist/cjs/utils/uuid.js +35 -0
  32. package/dist/esm/capture/jsError.js +45 -0
  33. package/dist/esm/capture/promiseError.js +46 -0
  34. package/dist/esm/capture/resourceError.js +24 -0
  35. package/dist/esm/capture/wechatError.js +92 -0
  36. package/dist/esm/compress/compression.js +82 -0
  37. package/dist/esm/config/index.js +28 -0
  38. package/dist/esm/core/fingerprint.js +12 -0
  39. package/dist/esm/core/httpClient.js +95 -0
  40. package/dist/esm/core/loggerSDK.js +650 -0
  41. package/dist/esm/core/queueManager.js +269 -0
  42. package/dist/esm/core/retryManager.js +129 -0
  43. package/dist/esm/index.js +5 -0
  44. package/dist/esm/stack/stacktrace.js +37 -0
  45. package/dist/esm/transport/beaconTransport.js +81 -0
  46. package/dist/esm/transport/pixelImageTransport.js +99 -0
  47. package/dist/esm/transport/transport.js +0 -0
  48. package/dist/esm/transport/transportAdapter.js +32 -0
  49. package/dist/esm/transport/wechatTransport.js +120 -0
  50. package/dist/esm/types/api.js +0 -0
  51. package/dist/esm/types/env.js +0 -0
  52. package/dist/esm/types/external.d.ts +21 -0
  53. package/dist/esm/types/logEvent.js +0 -0
  54. package/dist/esm/types/logEventLevel.js +0 -0
  55. package/dist/esm/types/sdkOptions.js +0 -0
  56. package/dist/esm/types/trackOptions.js +0 -0
  57. package/dist/esm/utils/environment.js +154 -0
  58. package/dist/esm/utils/session.js +7 -0
  59. package/dist/esm/utils/tools.js +76 -0
  60. package/dist/esm/utils/uuid.js +11 -0
  61. package/dist/types/capture/jsError.d.ts +2 -0
  62. package/dist/types/capture/promiseError.d.ts +2 -0
  63. package/dist/types/capture/resourceError.d.ts +2 -0
  64. package/dist/types/capture/wechatError.d.ts +3 -0
  65. package/dist/types/compress/compression.d.ts +10 -0
  66. package/dist/types/config/index.d.ts +9 -0
  67. package/dist/types/core/fingerprint.d.ts +8 -0
  68. package/dist/types/core/httpClient.d.ts +11 -0
  69. package/dist/{loggerSDK.d.ts → types/core/loggerSDK.d.ts} +27 -2
  70. package/dist/{queueManager.d.ts → types/core/queueManager.d.ts} +9 -1
  71. package/dist/{retryManager.d.ts → types/core/retryManager.d.ts} +0 -4
  72. package/dist/types/index.d.ts +1 -0
  73. package/dist/types/stack/stacktrace.d.ts +2 -0
  74. package/dist/types/transport/beaconTransport.d.ts +11 -0
  75. package/dist/types/transport/pixelImageTransport.d.ts +11 -0
  76. package/dist/types/transport/transport.d.ts +14 -0
  77. package/dist/types/transport/transportAdapter.d.ts +10 -0
  78. package/dist/types/transport/wechatTransport.d.ts +11 -0
  79. package/dist/types/types/api.d.ts +12 -0
  80. package/dist/types/types/env.d.ts +14 -0
  81. package/dist/types/types/logEvent.d.ts +57 -0
  82. package/dist/types/types/logEventLevel.d.ts +2 -0
  83. package/dist/{types.d.ts → types/types/sdkOptions.d.ts} +23 -42
  84. package/dist/types/types/trackOptions.d.ts +7 -0
  85. package/dist/types/utils/environment.d.ts +21 -0
  86. package/dist/types/utils/session.d.ts +1 -0
  87. package/dist/types/utils/tools.d.ts +12 -0
  88. package/dist/types/utils/uuid.d.ts +7 -0
  89. package/dist/umd/logger-sdk.min.js +1 -0
  90. package/package.json +29 -5
  91. package/dist/index.d.ts +0 -10
  92. package/dist/index.js +0 -13
  93. package/dist/loggerSDK.js +0 -560
  94. package/dist/queueManager.js +0 -186
  95. package/dist/retryManager.js +0 -224
  96. package/dist/transportAdapter.d.ts +0 -51
  97. package/dist/transportAdapter.js +0 -315
  98. package/dist/types.js +0 -1
  99. package/dist/utils.d.ts +0 -52
  100. package/dist/utils.js +0 -348
@@ -0,0 +1,269 @@
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 __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined")
11
+ return require.apply(this, arguments);
12
+ throw new Error('Dynamic require of "' + x + '" is not supported');
13
+ });
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+ var __async = (__this, __arguments, generator) => {
31
+ return new Promise((resolve, reject) => {
32
+ var fulfilled = (value) => {
33
+ try {
34
+ step(generator.next(value));
35
+ } catch (e) {
36
+ reject(e);
37
+ }
38
+ };
39
+ var rejected = (value) => {
40
+ try {
41
+ step(generator.throw(value));
42
+ } catch (e) {
43
+ reject(e);
44
+ }
45
+ };
46
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
47
+ step((generator = generator.apply(__this, __arguments)).next());
48
+ });
49
+ };
50
+
51
+ // src/core/queueManager.ts
52
+ import { isBrowser, isWeChatMiniProgram } from "../utils/environment";
53
+ import { logDebug, safeStringify } from "../utils/tools";
54
+ var QueueManager = class {
55
+ constructor(options) {
56
+ this.queue = [];
57
+ this.localforage = null;
58
+ this.opts = options;
59
+ this.storageKey = `${options.storagePrefix}_queue`;
60
+ this.loadLocalForage().then(() => {
61
+ if (this.opts.enableStorage) {
62
+ this.loadFromStorage();
63
+ }
64
+ });
65
+ }
66
+ loadLocalForage() {
67
+ return __async(this, null, function* () {
68
+ try {
69
+ if (isBrowser()) {
70
+ Promise.resolve().then(() => __toESM(__require("localforage"))).then((res) => {
71
+ this.localforage = res;
72
+ logDebug(!!this.opts.debug, res);
73
+ });
74
+ }
75
+ } catch (e) {
76
+ logDebug(!!this.opts.debug, "localforage load error", e);
77
+ }
78
+ return null;
79
+ });
80
+ }
81
+ /**
82
+ * 添加日志到队列
83
+ */
84
+ enqueue(event) {
85
+ if (this.queue.length >= this.opts.maxSize) {
86
+ this.queue.shift();
87
+ logDebug(!!this.opts.debug, "Queue full, dropped oldest event");
88
+ }
89
+ this.queue.push(event);
90
+ logDebug(!!this.opts.debug, "Enqueued event", event);
91
+ if (this.opts.enableStorage) {
92
+ this.saveToStorage();
93
+ }
94
+ return true;
95
+ }
96
+ /**
97
+ * 批量获取日志(不移除)
98
+ */
99
+ peek(count) {
100
+ return this.queue.slice(0, count);
101
+ }
102
+ /**
103
+ * 批量移除日志
104
+ */
105
+ dequeue(count) {
106
+ const items = this.queue.splice(0, count);
107
+ logDebug(!!this.opts.debug, `Dequeued ${items.length} events`);
108
+ if (this.opts.enableStorage) {
109
+ this.saveToStorage();
110
+ }
111
+ return items;
112
+ }
113
+ /**
114
+ * 获取队列长度
115
+ */
116
+ size() {
117
+ return this.queue.length;
118
+ }
119
+ /**
120
+ * 清空队列
121
+ */
122
+ clear() {
123
+ this.queue = [];
124
+ logDebug(!!this.opts.debug, "Queue cleared");
125
+ if (this.opts.enableStorage) {
126
+ this.removeFromStorage();
127
+ }
128
+ }
129
+ /**
130
+ * 从持久化存储加载队列
131
+ */
132
+ loadFromStorage() {
133
+ return __async(this, null, function* () {
134
+ try {
135
+ let stored = null;
136
+ if (isWeChatMiniProgram()) {
137
+ stored = wx.getStorageSync(this.storageKey);
138
+ } else if (isBrowser()) {
139
+ if (!this.localforage) {
140
+ yield this.loadLocalForage();
141
+ }
142
+ try {
143
+ const items = this.localforage ? yield this.localforage.getItem(this.storageKey) : null;
144
+ if (Array.isArray(items)) {
145
+ this.queue = items.slice(0, this.opts.maxSize);
146
+ logDebug(!!this.opts.debug, `Loaded ${this.queue.length} events from IndexedDB`);
147
+ return;
148
+ }
149
+ } catch (err) {
150
+ logDebug(!!this.opts.debug, "IndexedDB load error, falling back to localStorage", err);
151
+ }
152
+ if (typeof localStorage !== "undefined") {
153
+ const ls = localStorage.getItem(this.storageKey);
154
+ if (ls) {
155
+ try {
156
+ const parsed = JSON.parse(ls);
157
+ if (Array.isArray(parsed)) {
158
+ this.queue = parsed.slice(0, this.opts.maxSize);
159
+ logDebug(!!this.opts.debug, `Loaded ${this.queue.length} events from localStorage`);
160
+ }
161
+ } catch (e) {
162
+ }
163
+ }
164
+ }
165
+ return;
166
+ }
167
+ if (stored) {
168
+ const parsed = JSON.parse(stored);
169
+ if (Array.isArray(parsed)) {
170
+ this.queue = parsed.slice(0, this.opts.maxSize);
171
+ logDebug(!!this.opts.debug, `Loaded ${this.queue.length} events from storage`);
172
+ }
173
+ }
174
+ } catch (error) {
175
+ logDebug(!!this.opts.debug, "Failed to load queue from storage", error);
176
+ }
177
+ });
178
+ }
179
+ /**
180
+ * 保存队列到持久化存储
181
+ */
182
+ saveToStorage() {
183
+ try {
184
+ const data = safeStringify(this.queue);
185
+ if (isWeChatMiniProgram()) {
186
+ wx.setStorageSync(this.storageKey, data);
187
+ } else if (isBrowser()) {
188
+ const saveToLocalStorage = () => {
189
+ if (typeof localStorage !== "undefined") {
190
+ localStorage.setItem(this.storageKey, data);
191
+ logDebug(!!this.opts.debug, `Saved ${this.queue.length} events to localStorage`);
192
+ }
193
+ };
194
+ if (!this.localforage) {
195
+ this.loadLocalForage().then(() => {
196
+ if (this.localforage) {
197
+ return this.localforage.setItem(this.storageKey, this.queue).then(() => {
198
+ logDebug(!!this.opts.debug, `Saved ${this.queue.length} events to IndexedDB`);
199
+ }).catch((err) => {
200
+ logDebug(!!this.opts.debug, "IndexedDB save error, falling back to localStorage", err);
201
+ saveToLocalStorage();
202
+ });
203
+ }
204
+ saveToLocalStorage();
205
+ return null;
206
+ }).catch((err) => {
207
+ logDebug(!!this.opts.debug, "IndexedDB save error, falling back to localStorage", err);
208
+ saveToLocalStorage();
209
+ });
210
+ } else {
211
+ this.localforage.setItem(this.storageKey, this.queue).then(() => {
212
+ logDebug(!!this.opts.debug, `Saved ${this.queue.length} events to IndexedDB`);
213
+ }).catch((err) => {
214
+ logDebug(!!this.opts.debug, "IndexedDB save error, falling back to localStorage", err);
215
+ saveToLocalStorage();
216
+ });
217
+ }
218
+ }
219
+ } catch (error) {
220
+ logDebug(!!this.opts.debug, "Failed to save queue to storage", error);
221
+ }
222
+ }
223
+ /**
224
+ * 从持久化存储移除队列
225
+ */
226
+ removeFromStorage() {
227
+ try {
228
+ if (isWeChatMiniProgram()) {
229
+ wx.removeStorageSync(this.storageKey);
230
+ } else if (isBrowser()) {
231
+ const removeFromLocalStorage = () => {
232
+ if (typeof localStorage !== "undefined") {
233
+ localStorage.removeItem(this.storageKey);
234
+ logDebug(!!this.opts.debug, "Removed queue from localStorage");
235
+ }
236
+ };
237
+ if (!this.localforage) {
238
+ this.loadLocalForage().then(() => {
239
+ if (this.localforage) {
240
+ return this.localforage.removeItem(this.storageKey).then(() => {
241
+ logDebug(!!this.opts.debug, "Removed queue from IndexedDB");
242
+ }).catch((err) => {
243
+ logDebug(!!this.opts.debug, "IndexedDB remove error, falling back to localStorage", err);
244
+ removeFromLocalStorage();
245
+ });
246
+ }
247
+ removeFromLocalStorage();
248
+ return null;
249
+ }).catch((err) => {
250
+ logDebug(!!this.opts.debug, "IndexedDB remove error, falling back to localStorage", err);
251
+ removeFromLocalStorage();
252
+ });
253
+ } else {
254
+ this.localforage.removeItem(this.storageKey).then(() => {
255
+ logDebug(!!this.opts.debug, "Removed queue from IndexedDB");
256
+ }).catch((err) => {
257
+ logDebug(!!this.opts.debug, "IndexedDB remove error, falling back to localStorage", err);
258
+ removeFromLocalStorage();
259
+ });
260
+ }
261
+ }
262
+ } catch (error) {
263
+ logDebug(!!this.opts.debug, "Failed to remove queue from storage", error);
264
+ }
265
+ }
266
+ };
267
+ export {
268
+ QueueManager
269
+ };
@@ -0,0 +1,129 @@
1
+ var __pow = Math.pow;
2
+ var __async = (__this, __arguments, generator) => {
3
+ return new Promise((resolve, reject) => {
4
+ var fulfilled = (value) => {
5
+ try {
6
+ step(generator.next(value));
7
+ } catch (e) {
8
+ reject(e);
9
+ }
10
+ };
11
+ var rejected = (value) => {
12
+ try {
13
+ step(generator.throw(value));
14
+ } catch (e) {
15
+ reject(e);
16
+ }
17
+ };
18
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
19
+ step((generator = generator.apply(__this, __arguments)).next());
20
+ });
21
+ };
22
+
23
+ // src/core/retryManager.ts
24
+ import { logDebug } from "../utils/tools";
25
+ var RetryManager = class {
26
+ constructor(options) {
27
+ this.retryingTasks = /* @__PURE__ */ new Map();
28
+ this.opts = options;
29
+ }
30
+ /**
31
+ * 执行带重试的任务
32
+ * @param taskId - 任务唯一标识
33
+ * @param fn - 要执行的异步函数
34
+ * @returns Promise
35
+ */
36
+ executeWithRetry(taskId, fn) {
37
+ return __async(this, null, function* () {
38
+ if (this.retryingTasks.has(taskId)) {
39
+ 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 = yield 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
+ */
64
+ executeTask(task) {
65
+ return __async(this, null, function* () {
66
+ while (task.retries <= task.maxRetries) {
67
+ try {
68
+ const result = yield task.fn();
69
+ if (task.retries > 0) {
70
+ logDebug(!!this.opts.debug, `Task ${task.id} succeeded after ${task.retries} retries`);
71
+ }
72
+ return result;
73
+ } catch (error) {
74
+ task.retries += 1;
75
+ if (task.retries > task.maxRetries) {
76
+ logDebug(!!this.opts.debug, `Task ${task.id} failed after ${task.maxRetries} retries`);
77
+ throw error;
78
+ }
79
+ const delay = RetryManager.calculateDelay(task.retries, task.baseDelay, task.useBackoff);
80
+ logDebug(
81
+ !!this.opts.debug,
82
+ `Task ${task.id} failed (attempt ${task.retries}/${task.maxRetries}), retrying in ${delay}ms`
83
+ );
84
+ yield RetryManager.sleep(delay);
85
+ }
86
+ }
87
+ throw new Error(`Task ${task.id} exceeded max retries`);
88
+ });
89
+ }
90
+ /**
91
+ * 计算延迟时间
92
+ * @param attempt - 当前重试次数
93
+ * @param baseDelay - 基础延迟时间
94
+ * @param useBackoff - 是否使用指数退避
95
+ * @returns 延迟时间(毫秒)
96
+ */
97
+ static calculateDelay(attempt, baseDelay, useBackoff) {
98
+ if (!useBackoff) {
99
+ return baseDelay;
100
+ }
101
+ const factor = __pow(2, attempt - 1);
102
+ const delay = baseDelay * factor;
103
+ const jitterRatio = 0.3;
104
+ const maxDelay = 3e4;
105
+ const jitter = Math.random() * jitterRatio * delay;
106
+ return Math.min(delay + jitter, maxDelay);
107
+ }
108
+ /**
109
+ * 睡眠函数
110
+ */
111
+ static sleep(ms) {
112
+ return new Promise((resolve) => setTimeout(resolve, ms));
113
+ }
114
+ /**
115
+ * 获取正在重试的任务数量
116
+ */
117
+ getRetryingCount() {
118
+ return this.retryingTasks.size;
119
+ }
120
+ /**
121
+ * 清空所有重试任务
122
+ */
123
+ clear() {
124
+ this.retryingTasks.clear();
125
+ }
126
+ };
127
+ export {
128
+ RetryManager
129
+ };
@@ -0,0 +1,5 @@
1
+ // src/index.ts
2
+ import { LoggerSDK } from "./core/loggerSDK";
3
+ export {
4
+ LoggerSDK
5
+ };
@@ -0,0 +1,37 @@
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+
22
+ // src/stack/stacktrace.ts
23
+ import StackTrace from "stacktrace-js";
24
+ function parseStack(error) {
25
+ return __async(this, null, function* () {
26
+ const frames = yield StackTrace.fromError(error);
27
+ return frames.slice(0, 5).map((f) => ({
28
+ file: f.fileName || "",
29
+ line: f.lineNumber || 0,
30
+ column: f.columnNumber || 0,
31
+ function: f.functionName || void 0
32
+ }));
33
+ });
34
+ }
35
+ export {
36
+ parseStack
37
+ };
@@ -0,0 +1,81 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+
41
+ // src/transport/beaconTransport.ts
42
+ import { gzipCompress } from "../compress/compression";
43
+ import { getReportApi } from "../config";
44
+ import { isBrowser } from "../utils/environment";
45
+ import { logDebug, safeStringify } from "../utils/tools";
46
+ var BeaconTransport = class {
47
+ constructor(opts) {
48
+ /** 传输器名称 */
49
+ this.name = "beacon";
50
+ this.opts = opts;
51
+ }
52
+ // eslint-disable-next-line class-methods-use-this
53
+ isSupported() {
54
+ return isBrowser() && typeof navigator !== "undefined" && navigator.sendBeacon && typeof navigator.sendBeacon === "function";
55
+ }
56
+ send(payload) {
57
+ return __async(this, null, function* () {
58
+ var _a, _b, _c, _d, _e;
59
+ let body = typeof payload === "string" ? payload : safeStringify(payload);
60
+ const endpoint = getReportApi(((_a = this.opts) == null ? void 0 : _a.env) || "develop");
61
+ let contentType = "application/json";
62
+ if (((_b = this.opts) == null ? void 0 : _b.enableGzip) && (!((_c = this.opts) == null ? void 0 : _c.gzipOnlyInBatchMode) || payload.items.length > 0)) {
63
+ const compressedItems = yield gzipCompress(safeStringify(payload.items));
64
+ body = safeStringify(__spreadProps(__spreadValues({}, payload), {
65
+ items: compressedItems
66
+ }));
67
+ contentType = "application/json; charset=utf-8";
68
+ }
69
+ const blob = new Blob([body], { type: contentType });
70
+ const success = navigator.sendBeacon(endpoint, blob);
71
+ logDebug(!!((_d = this.opts) == null ? void 0 : _d.debug), "sendBeacon result", success);
72
+ if (!success) {
73
+ logDebug(!!((_e = this.opts) == null ? void 0 : _e.debug), "sendBeacon failed (queue full or other error)");
74
+ }
75
+ return Promise.resolve();
76
+ });
77
+ }
78
+ };
79
+ export {
80
+ BeaconTransport
81
+ };
@@ -0,0 +1,99 @@
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+
22
+ // src/transport/pixelImageTransport.ts
23
+ import { Base64 } from "js-base64";
24
+ import { isBrowser } from "../utils/environment";
25
+ import { logDebug, now, safeStringify } from "../utils/tools";
26
+ import { getPixelBatchApi } from "../config";
27
+ import { gzipCompress } from "../compress/compression";
28
+ var PixelImageTransport = class {
29
+ constructor(opts) {
30
+ /** 传输器名称 */
31
+ this.name = "image";
32
+ this.opts = opts;
33
+ }
34
+ // eslint-disable-next-line class-methods-use-this
35
+ isSupported() {
36
+ return isBrowser() && typeof Image !== "undefined";
37
+ }
38
+ send(payload) {
39
+ return __async(this, null, function* () {
40
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
41
+ const body = safeStringify(payload.items);
42
+ const endpoint = getPixelBatchApi(((_a = this.opts) == null ? void 0 : _a.env) || "develop");
43
+ const param = "items";
44
+ const maxLen = ((_b = this.opts) == null ? void 0 : _b.maxPixelUrlLen) || 8192;
45
+ let compressedBody;
46
+ if (((_c = this.opts) == null ? void 0 : _c.enableGzip) && (!((_d = this.opts) == null ? void 0 : _d.gzipOnlyInBatchMode) || payload.items.length > 0)) {
47
+ const t = now();
48
+ logDebug(!!((_e = this.opts) == null ? void 0 : _e.debug), "PixelImage request gzip compress body: ", body);
49
+ compressedBody = yield gzipCompress(body);
50
+ logDebug(!!((_f = this.opts) == null ? void 0 : _f.debug), "PixelImage request gzip compress cost: ", now() - t);
51
+ logDebug(!!((_g = this.opts) == null ? void 0 : _g.debug), `original body size: ${body.length}, compressed body size: ${compressedBody.length}`);
52
+ logDebug(!!((_h = this.opts) == null ? void 0 : _h.debug), "PixelImage request gzip compress body: ", compressedBody);
53
+ } else {
54
+ compressedBody = Base64.encode(body, false);
55
+ }
56
+ const cacheBuster = `_=${Date.now()}`;
57
+ const qs = `appId=${((_i = this.opts) == null ? void 0 : _i.appId) || ""}&appStage=${((_j = this.opts) == null ? void 0 : _j.logStage) || ""}&${param}=${encodeURIComponent(compressedBody)}&gzip=${((_k = this.opts) == null ? void 0 : _k.enableGzip) ? 1 : 0}&${cacheBuster}`;
58
+ const url = endpoint.includes("?") ? `${endpoint}&${qs}` : `${endpoint}?${qs}`;
59
+ if (url.length > maxLen) {
60
+ logDebug(!!((_l = this.opts) == null ? void 0 : _l.debug), `URL too long (${url.length} > ${maxLen})`);
61
+ }
62
+ return new Promise((resolve, reject) => {
63
+ const img = new Image();
64
+ let timeoutId = null;
65
+ let settled = false;
66
+ timeoutId = setTimeout(() => {
67
+ if (!settled) {
68
+ settled = true;
69
+ img.src = "";
70
+ reject(new Error("Image request timeout after 5000ms"));
71
+ }
72
+ }, 5e3);
73
+ img.onload = () => {
74
+ if (timeoutId)
75
+ clearTimeout(timeoutId);
76
+ if (!settled) {
77
+ settled = true;
78
+ resolve();
79
+ }
80
+ };
81
+ img.onerror = (event, source, lineno, colno, error) => {
82
+ var _a2, _b2;
83
+ logDebug(!!((_a2 = this.opts) == null ? void 0 : _a2.debug), "Image request failed", event, source, lineno, colno, error);
84
+ if (timeoutId)
85
+ clearTimeout(timeoutId);
86
+ if (!settled) {
87
+ settled = true;
88
+ logDebug(!!((_b2 = this.opts) == null ? void 0 : _b2.debug), "Image request failed", event, source, lineno, colno, error);
89
+ resolve();
90
+ }
91
+ };
92
+ img.src = url;
93
+ });
94
+ });
95
+ }
96
+ };
97
+ export {
98
+ PixelImageTransport
99
+ };
File without changes
@@ -0,0 +1,32 @@
1
+ // src/transport/transportAdapter.ts
2
+ import { isWeChatMiniProgram } from "../utils/environment";
3
+ import { BeaconTransport } from "./beaconTransport";
4
+ import { PixelImageTransport } from "./pixelImageTransport";
5
+ import { WechatTransport } from "./wechatTransport";
6
+ var TransportAdapter = class {
7
+ constructor(opts) {
8
+ this.beaconTransport = new BeaconTransport(opts);
9
+ this.pixelImageTransport = new PixelImageTransport(opts);
10
+ this.wechatTransport = new WechatTransport(opts);
11
+ }
12
+ static getInstance(opts) {
13
+ if (!TransportAdapter.instance) {
14
+ TransportAdapter.instance = new TransportAdapter(opts);
15
+ }
16
+ return TransportAdapter.instance;
17
+ }
18
+ getTransporter() {
19
+ if (isWeChatMiniProgram()) {
20
+ return this.wechatTransport;
21
+ }
22
+ const transports = [this.beaconTransport, this.pixelImageTransport];
23
+ const transporter = transports.find((t) => t.isSupported());
24
+ if (!transporter) {
25
+ return this.pixelImageTransport;
26
+ }
27
+ return transporter;
28
+ }
29
+ };
30
+ export {
31
+ TransportAdapter
32
+ };