@qhr123/sa2kit 0.3.0 → 0.4.0
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/dist/analytics/index.d.mts +237 -4
- package/dist/analytics/index.d.ts +237 -4
- package/dist/analytics/index.js +733 -5
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +715 -6
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/chunk-BJTO5JO5.mjs +10 -0
- package/dist/chunk-BJTO5JO5.mjs.map +1 -0
- package/dist/chunk-DGUM43GV.js +12 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/index.mjs +1 -0
- package/dist/i18n/index.d.mts +75 -1
- package/dist/i18n/index.d.ts +75 -1
- package/dist/i18n/index.js +179 -0
- package/dist/i18n/index.js.map +1 -1
- package/dist/i18n/index.mjs +176 -1
- package/dist/i18n/index.mjs.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/dist/logger/index.js +1 -0
- package/dist/logger/index.mjs +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/index.mjs +1 -0
- package/dist/universalExport/index.js +2 -0
- package/dist/universalExport/index.js.map +1 -1
- package/dist/universalExport/index.mjs +2 -0
- package/dist/universalExport/index.mjs.map +1 -1
- package/dist/universalFile/index.js +2 -0
- package/dist/universalFile/index.js.map +1 -1
- package/dist/universalFile/index.mjs +2 -0
- package/dist/universalFile/index.mjs.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.mjs +1 -0
- package/package.json +8 -3
package/dist/analytics/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import '../chunk-BJTO5JO5.mjs';
|
|
1
2
|
import { useEffect, useCallback, useRef } from 'react';
|
|
2
3
|
|
|
3
4
|
// src/analytics/types.ts
|
|
@@ -705,6 +706,30 @@ function createDesktopConfig(appId, options = {}) {
|
|
|
705
706
|
};
|
|
706
707
|
}
|
|
707
708
|
|
|
709
|
+
// src/analytics/client/singleton.ts
|
|
710
|
+
var instances = /* @__PURE__ */ new Map();
|
|
711
|
+
function createAnalytics(instanceKey, config) {
|
|
712
|
+
if (!instances.has(instanceKey)) {
|
|
713
|
+
instances.set(instanceKey, new Analytics(config));
|
|
714
|
+
}
|
|
715
|
+
return instances.get(instanceKey);
|
|
716
|
+
}
|
|
717
|
+
function getAnalyticsInstance(instanceKey) {
|
|
718
|
+
return instances.get(instanceKey) || null;
|
|
719
|
+
}
|
|
720
|
+
function resetAnalytics(instanceKey) {
|
|
721
|
+
instances.delete(instanceKey);
|
|
722
|
+
}
|
|
723
|
+
function resetAllAnalytics() {
|
|
724
|
+
instances.clear();
|
|
725
|
+
}
|
|
726
|
+
function isAnalyticsInitialized(instanceKey) {
|
|
727
|
+
return instances.has(instanceKey);
|
|
728
|
+
}
|
|
729
|
+
function getAllInstanceKeys() {
|
|
730
|
+
return Array.from(instances.keys());
|
|
731
|
+
}
|
|
732
|
+
|
|
708
733
|
// src/analytics/utils/helpers.ts
|
|
709
734
|
function throttle(func, wait) {
|
|
710
735
|
let timeout = null;
|
|
@@ -858,7 +883,7 @@ function Track(eventName, priority = 1 /* NORMAL */) {
|
|
|
858
883
|
return function(_target, propertyKey, descriptor) {
|
|
859
884
|
const originalMethod = descriptor.value;
|
|
860
885
|
descriptor.value = async function(...args) {
|
|
861
|
-
const analytics =
|
|
886
|
+
const analytics = getAnalyticsInstance2(this);
|
|
862
887
|
const finalEventName = eventName || propertyKey;
|
|
863
888
|
const startTime = Date.now();
|
|
864
889
|
try {
|
|
@@ -895,7 +920,7 @@ function TrackClick(eventName) {
|
|
|
895
920
|
return function(_target, propertyKey, descriptor) {
|
|
896
921
|
const originalMethod = descriptor.value;
|
|
897
922
|
descriptor.value = function(...args) {
|
|
898
|
-
const analytics =
|
|
923
|
+
const analytics = getAnalyticsInstance2(this);
|
|
899
924
|
const finalEventName = eventName || propertyKey;
|
|
900
925
|
analytics?.track(
|
|
901
926
|
"click" /* CLICK */,
|
|
@@ -914,7 +939,7 @@ function TrackPerformance(metricName) {
|
|
|
914
939
|
return function(_target, propertyKey, descriptor) {
|
|
915
940
|
const originalMethod = descriptor.value;
|
|
916
941
|
descriptor.value = async function(...args) {
|
|
917
|
-
const analytics =
|
|
942
|
+
const analytics = getAnalyticsInstance2(this);
|
|
918
943
|
const finalMetricName = metricName || propertyKey;
|
|
919
944
|
const startTime = performance.now();
|
|
920
945
|
try {
|
|
@@ -943,7 +968,7 @@ function CatchError(_eventName) {
|
|
|
943
968
|
try {
|
|
944
969
|
return await originalMethod.apply(this, args);
|
|
945
970
|
} catch (error) {
|
|
946
|
-
const analytics =
|
|
971
|
+
const analytics = getAnalyticsInstance2(this);
|
|
947
972
|
analytics?.trackError(
|
|
948
973
|
error instanceof Error ? error.message : String(error),
|
|
949
974
|
error instanceof Error ? error.stack : void 0,
|
|
@@ -959,7 +984,7 @@ function CatchError(_eventName) {
|
|
|
959
984
|
return descriptor;
|
|
960
985
|
};
|
|
961
986
|
}
|
|
962
|
-
function
|
|
987
|
+
function getAnalyticsInstance2(instance) {
|
|
963
988
|
if (instance.analytics) {
|
|
964
989
|
return instance.analytics;
|
|
965
990
|
}
|
|
@@ -1132,9 +1157,693 @@ function useAutoTracking(analytics, options = {}) {
|
|
|
1132
1157
|
}, [analytics, trackErrors]);
|
|
1133
1158
|
}
|
|
1134
1159
|
|
|
1160
|
+
// src/analytics/adapters/web.ts
|
|
1161
|
+
var WebStorageAdapter = class {
|
|
1162
|
+
constructor() {
|
|
1163
|
+
this.EVENTS_KEY = "analytics:events";
|
|
1164
|
+
this.DEVICE_INFO_KEY = "analytics:device_info";
|
|
1165
|
+
this.SESSION_ID_KEY = "analytics:session_id";
|
|
1166
|
+
}
|
|
1167
|
+
async saveEvents(events) {
|
|
1168
|
+
try {
|
|
1169
|
+
if (typeof window !== "undefined") {
|
|
1170
|
+
localStorage.setItem(this.EVENTS_KEY, JSON.stringify(events));
|
|
1171
|
+
}
|
|
1172
|
+
} catch (error) {
|
|
1173
|
+
console.error("Failed to save events:", error);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
async getEvents() {
|
|
1177
|
+
try {
|
|
1178
|
+
if (typeof window !== "undefined") {
|
|
1179
|
+
const data = localStorage.getItem(this.EVENTS_KEY);
|
|
1180
|
+
return data ? JSON.parse(data) : [];
|
|
1181
|
+
}
|
|
1182
|
+
return [];
|
|
1183
|
+
} catch (error) {
|
|
1184
|
+
console.error("Failed to get events:", error);
|
|
1185
|
+
return [];
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
async clearEvents() {
|
|
1189
|
+
try {
|
|
1190
|
+
if (typeof window !== "undefined") {
|
|
1191
|
+
localStorage.removeItem(this.EVENTS_KEY);
|
|
1192
|
+
}
|
|
1193
|
+
} catch (error) {
|
|
1194
|
+
console.error("Failed to clear events:", error);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
async saveDeviceInfo(info) {
|
|
1198
|
+
try {
|
|
1199
|
+
if (typeof window !== "undefined") {
|
|
1200
|
+
localStorage.setItem(this.DEVICE_INFO_KEY, JSON.stringify(info));
|
|
1201
|
+
}
|
|
1202
|
+
} catch (error) {
|
|
1203
|
+
console.error("Failed to save device info:", error);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
async getDeviceInfo() {
|
|
1207
|
+
try {
|
|
1208
|
+
if (typeof window !== "undefined") {
|
|
1209
|
+
const data = localStorage.getItem(this.DEVICE_INFO_KEY);
|
|
1210
|
+
return data ? JSON.parse(data) : null;
|
|
1211
|
+
}
|
|
1212
|
+
return null;
|
|
1213
|
+
} catch (error) {
|
|
1214
|
+
console.error("Failed to get device info:", error);
|
|
1215
|
+
return null;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
async saveSessionId(sessionId) {
|
|
1219
|
+
try {
|
|
1220
|
+
if (typeof window !== "undefined") {
|
|
1221
|
+
sessionStorage.setItem(this.SESSION_ID_KEY, sessionId);
|
|
1222
|
+
}
|
|
1223
|
+
} catch (error) {
|
|
1224
|
+
console.error("Failed to save session ID:", error);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
async getSessionId() {
|
|
1228
|
+
try {
|
|
1229
|
+
if (typeof window !== "undefined") {
|
|
1230
|
+
return sessionStorage.getItem(this.SESSION_ID_KEY);
|
|
1231
|
+
}
|
|
1232
|
+
return null;
|
|
1233
|
+
} catch (error) {
|
|
1234
|
+
console.error("Failed to get session ID:", error);
|
|
1235
|
+
return null;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
};
|
|
1239
|
+
var WebNetworkAdapter = class {
|
|
1240
|
+
async upload(url, events) {
|
|
1241
|
+
try {
|
|
1242
|
+
const response = await fetch(url, {
|
|
1243
|
+
method: "POST",
|
|
1244
|
+
headers: {
|
|
1245
|
+
"Content-Type": "application/json"
|
|
1246
|
+
},
|
|
1247
|
+
body: JSON.stringify({
|
|
1248
|
+
events,
|
|
1249
|
+
timestamp: Date.now()
|
|
1250
|
+
}),
|
|
1251
|
+
// 使用 keepalive 确保页面关闭时也能发送
|
|
1252
|
+
keepalive: true
|
|
1253
|
+
});
|
|
1254
|
+
if (response.ok) {
|
|
1255
|
+
const data = await response.json();
|
|
1256
|
+
return {
|
|
1257
|
+
success: true,
|
|
1258
|
+
message: data.message,
|
|
1259
|
+
code: response.status
|
|
1260
|
+
};
|
|
1261
|
+
} else {
|
|
1262
|
+
return {
|
|
1263
|
+
success: false,
|
|
1264
|
+
message: `HTTP ${response.status}`,
|
|
1265
|
+
code: response.status
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
return {
|
|
1270
|
+
success: false,
|
|
1271
|
+
message: error instanceof Error ? error.message : "Network error",
|
|
1272
|
+
code: 0
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
async isOnline() {
|
|
1277
|
+
if (typeof navigator !== "undefined" && "onLine" in navigator) {
|
|
1278
|
+
return navigator.onLine;
|
|
1279
|
+
}
|
|
1280
|
+
return true;
|
|
1281
|
+
}
|
|
1282
|
+
};
|
|
1283
|
+
var WebDeviceAdapter = class {
|
|
1284
|
+
async getDeviceInfo() {
|
|
1285
|
+
return {
|
|
1286
|
+
device_id: await this.generateDeviceId(),
|
|
1287
|
+
os_name: this.getOSName(),
|
|
1288
|
+
os_version: this.getOSVersion(),
|
|
1289
|
+
screen_width: typeof window !== "undefined" ? window.screen.width : 0,
|
|
1290
|
+
screen_height: typeof window !== "undefined" ? window.screen.height : 0,
|
|
1291
|
+
language: typeof navigator !== "undefined" ? navigator.language : "en",
|
|
1292
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
1293
|
+
device_model: this.getBrowserName(),
|
|
1294
|
+
device_brand: this.getBrowserVersion()
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
async generateDeviceId() {
|
|
1298
|
+
if (typeof window !== "undefined") {
|
|
1299
|
+
let deviceId = localStorage.getItem("analytics:device_id");
|
|
1300
|
+
if (!deviceId) {
|
|
1301
|
+
deviceId = `web_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
1302
|
+
localStorage.setItem("analytics:device_id", deviceId);
|
|
1303
|
+
}
|
|
1304
|
+
return deviceId;
|
|
1305
|
+
}
|
|
1306
|
+
return `web_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
1307
|
+
}
|
|
1308
|
+
getOSName() {
|
|
1309
|
+
if (typeof navigator === "undefined") return "unknown";
|
|
1310
|
+
const userAgent = navigator.userAgent;
|
|
1311
|
+
if (userAgent.indexOf("Win") !== -1) return "Windows";
|
|
1312
|
+
if (userAgent.indexOf("Mac") !== -1) return "MacOS";
|
|
1313
|
+
if (userAgent.indexOf("Linux") !== -1) return "Linux";
|
|
1314
|
+
if (userAgent.indexOf("Android") !== -1) return "Android";
|
|
1315
|
+
if (userAgent.indexOf("iOS") !== -1) return "iOS";
|
|
1316
|
+
return "unknown";
|
|
1317
|
+
}
|
|
1318
|
+
getOSVersion() {
|
|
1319
|
+
if (typeof navigator === "undefined") return "unknown";
|
|
1320
|
+
const userAgent = navigator.userAgent;
|
|
1321
|
+
const match = userAgent.match(/\(([^)]+)\)/);
|
|
1322
|
+
return match && match[1] ? match[1] : "unknown";
|
|
1323
|
+
}
|
|
1324
|
+
getBrowserName() {
|
|
1325
|
+
if (typeof navigator === "undefined") return "unknown";
|
|
1326
|
+
const userAgent = navigator.userAgent;
|
|
1327
|
+
if (userAgent.indexOf("Chrome") !== -1) return "Chrome";
|
|
1328
|
+
if (userAgent.indexOf("Safari") !== -1) return "Safari";
|
|
1329
|
+
if (userAgent.indexOf("Firefox") !== -1) return "Firefox";
|
|
1330
|
+
if (userAgent.indexOf("Edge") !== -1) return "Edge";
|
|
1331
|
+
return "unknown";
|
|
1332
|
+
}
|
|
1333
|
+
getBrowserVersion() {
|
|
1334
|
+
if (typeof navigator === "undefined") return "unknown";
|
|
1335
|
+
const userAgent = navigator.userAgent;
|
|
1336
|
+
const match = userAgent.match(/(Chrome|Safari|Firefox|Edge)\/(\d+)/);
|
|
1337
|
+
return match && match[2] ? match[2] : "unknown";
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1340
|
+
var webAdapter = {
|
|
1341
|
+
storage: new WebStorageAdapter(),
|
|
1342
|
+
network: new WebNetworkAdapter(),
|
|
1343
|
+
device: new WebDeviceAdapter()
|
|
1344
|
+
};
|
|
1345
|
+
|
|
1346
|
+
// src/analytics/adapters/mobile.ts
|
|
1347
|
+
var MobileStorageAdapter = class {
|
|
1348
|
+
// 需要注入具体的存储实现
|
|
1349
|
+
constructor(storage) {
|
|
1350
|
+
this.storage = storage;
|
|
1351
|
+
this.EVENTS_KEY = "@analytics:events";
|
|
1352
|
+
this.DEVICE_INFO_KEY = "@analytics:device_info";
|
|
1353
|
+
this.SESSION_ID_KEY = "@analytics:session_id";
|
|
1354
|
+
}
|
|
1355
|
+
async saveEvents(events) {
|
|
1356
|
+
try {
|
|
1357
|
+
await this.storage.setItem(this.EVENTS_KEY, JSON.stringify(events));
|
|
1358
|
+
} catch (error) {
|
|
1359
|
+
console.error("Failed to save events:", error);
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
async getEvents() {
|
|
1363
|
+
try {
|
|
1364
|
+
const data = await this.storage.getItem(this.EVENTS_KEY);
|
|
1365
|
+
return data ? JSON.parse(data) : [];
|
|
1366
|
+
} catch (error) {
|
|
1367
|
+
console.error("Failed to get events:", error);
|
|
1368
|
+
return [];
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
async clearEvents() {
|
|
1372
|
+
try {
|
|
1373
|
+
await this.storage.removeItem(this.EVENTS_KEY);
|
|
1374
|
+
} catch (error) {
|
|
1375
|
+
console.error("Failed to clear events:", error);
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
async saveDeviceInfo(info) {
|
|
1379
|
+
try {
|
|
1380
|
+
await this.storage.setItem(this.DEVICE_INFO_KEY, JSON.stringify(info));
|
|
1381
|
+
} catch (error) {
|
|
1382
|
+
console.error("Failed to save device info:", error);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
async getDeviceInfo() {
|
|
1386
|
+
try {
|
|
1387
|
+
const data = await this.storage.getItem(this.DEVICE_INFO_KEY);
|
|
1388
|
+
return data ? JSON.parse(data) : null;
|
|
1389
|
+
} catch (error) {
|
|
1390
|
+
console.error("Failed to get device info:", error);
|
|
1391
|
+
return null;
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
async saveSessionId(sessionId) {
|
|
1395
|
+
try {
|
|
1396
|
+
await this.storage.setItem(this.SESSION_ID_KEY, sessionId);
|
|
1397
|
+
} catch (error) {
|
|
1398
|
+
console.error("Failed to save session ID:", error);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
async getSessionId() {
|
|
1402
|
+
try {
|
|
1403
|
+
return await this.storage.getItem(this.SESSION_ID_KEY);
|
|
1404
|
+
} catch (error) {
|
|
1405
|
+
console.error("Failed to get session ID:", error);
|
|
1406
|
+
return null;
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
};
|
|
1410
|
+
var MobileNetworkAdapter = class {
|
|
1411
|
+
// 需要注入网络检查函数
|
|
1412
|
+
constructor(netInfo) {
|
|
1413
|
+
this.netInfo = netInfo;
|
|
1414
|
+
}
|
|
1415
|
+
async upload(url, events) {
|
|
1416
|
+
try {
|
|
1417
|
+
const response = await fetch(url, {
|
|
1418
|
+
method: "POST",
|
|
1419
|
+
headers: {
|
|
1420
|
+
"Content-Type": "application/json"
|
|
1421
|
+
},
|
|
1422
|
+
body: JSON.stringify({
|
|
1423
|
+
events,
|
|
1424
|
+
timestamp: Date.now()
|
|
1425
|
+
})
|
|
1426
|
+
});
|
|
1427
|
+
if (response.ok) {
|
|
1428
|
+
const data = await response.json();
|
|
1429
|
+
return {
|
|
1430
|
+
success: true,
|
|
1431
|
+
message: data.message,
|
|
1432
|
+
code: response.status
|
|
1433
|
+
};
|
|
1434
|
+
} else {
|
|
1435
|
+
return {
|
|
1436
|
+
success: false,
|
|
1437
|
+
message: `HTTP ${response.status}`,
|
|
1438
|
+
code: response.status
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
} catch (error) {
|
|
1442
|
+
return {
|
|
1443
|
+
success: false,
|
|
1444
|
+
message: error instanceof Error ? error.message : "Network error",
|
|
1445
|
+
code: 0
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
async isOnline() {
|
|
1450
|
+
try {
|
|
1451
|
+
if (this.netInfo) {
|
|
1452
|
+
const state = await this.netInfo.fetch();
|
|
1453
|
+
return state.isConnected ?? false;
|
|
1454
|
+
}
|
|
1455
|
+
return true;
|
|
1456
|
+
} catch (error) {
|
|
1457
|
+
return true;
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
};
|
|
1461
|
+
var MobileDeviceAdapter = class {
|
|
1462
|
+
// 需要注入设备信息获取函数
|
|
1463
|
+
constructor(deviceInfoModule) {
|
|
1464
|
+
this.deviceInfoModule = deviceInfoModule;
|
|
1465
|
+
}
|
|
1466
|
+
async getDeviceInfo() {
|
|
1467
|
+
try {
|
|
1468
|
+
const info = this.deviceInfoModule;
|
|
1469
|
+
return {
|
|
1470
|
+
device_id: info ? await info.getUniqueId() : await this.generateDeviceId(),
|
|
1471
|
+
device_model: info ? await info.getModel() : "unknown",
|
|
1472
|
+
device_brand: info ? await info.getBrand() : "unknown",
|
|
1473
|
+
os_name: info ? await info.getSystemName() : "unknown",
|
|
1474
|
+
os_version: info ? await info.getSystemVersion() : "unknown",
|
|
1475
|
+
screen_width: typeof window !== "undefined" ? window.screen.width : 0,
|
|
1476
|
+
screen_height: typeof window !== "undefined" ? window.screen.height : 0,
|
|
1477
|
+
language: typeof navigator !== "undefined" ? navigator.language : "en",
|
|
1478
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
1479
|
+
};
|
|
1480
|
+
} catch (error) {
|
|
1481
|
+
console.error("Failed to get device info:", error);
|
|
1482
|
+
return this.getDefaultDeviceInfo();
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
async generateDeviceId() {
|
|
1486
|
+
const timestamp = Date.now();
|
|
1487
|
+
const random = Math.random().toString(36).substring(2, 15);
|
|
1488
|
+
return `mobile_${timestamp}_${random}`;
|
|
1489
|
+
}
|
|
1490
|
+
getDefaultDeviceInfo() {
|
|
1491
|
+
return {
|
|
1492
|
+
device_id: `mobile_${Date.now()}`,
|
|
1493
|
+
os_name: "unknown",
|
|
1494
|
+
os_version: "unknown",
|
|
1495
|
+
screen_width: 0,
|
|
1496
|
+
screen_height: 0,
|
|
1497
|
+
language: "en",
|
|
1498
|
+
timezone: "UTC"
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
};
|
|
1502
|
+
|
|
1503
|
+
// src/analytics/adapters/miniapp.ts
|
|
1504
|
+
var MiniappStorageAdapter = class {
|
|
1505
|
+
// 需要注入 Taro 的存储 API
|
|
1506
|
+
constructor(storage) {
|
|
1507
|
+
this.storage = storage;
|
|
1508
|
+
this.EVENTS_KEY = "analytics_events";
|
|
1509
|
+
this.DEVICE_INFO_KEY = "analytics_device_info";
|
|
1510
|
+
this.SESSION_ID_KEY = "analytics_session_id";
|
|
1511
|
+
}
|
|
1512
|
+
async saveEvents(events) {
|
|
1513
|
+
try {
|
|
1514
|
+
if (this.storage) {
|
|
1515
|
+
this.storage.setStorageSync(this.EVENTS_KEY, events);
|
|
1516
|
+
}
|
|
1517
|
+
} catch (error) {
|
|
1518
|
+
console.error("Failed to save events:", error);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
async getEvents() {
|
|
1522
|
+
try {
|
|
1523
|
+
if (this.storage) {
|
|
1524
|
+
const data = this.storage.getStorageSync(this.EVENTS_KEY);
|
|
1525
|
+
return data || [];
|
|
1526
|
+
}
|
|
1527
|
+
return [];
|
|
1528
|
+
} catch (error) {
|
|
1529
|
+
console.error("Failed to get events:", error);
|
|
1530
|
+
return [];
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
async clearEvents() {
|
|
1534
|
+
try {
|
|
1535
|
+
if (this.storage) {
|
|
1536
|
+
this.storage.removeStorageSync(this.EVENTS_KEY);
|
|
1537
|
+
}
|
|
1538
|
+
} catch (error) {
|
|
1539
|
+
console.error("Failed to clear events:", error);
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
async saveDeviceInfo(info) {
|
|
1543
|
+
try {
|
|
1544
|
+
if (this.storage) {
|
|
1545
|
+
this.storage.setStorageSync(this.DEVICE_INFO_KEY, info);
|
|
1546
|
+
}
|
|
1547
|
+
} catch (error) {
|
|
1548
|
+
console.error("Failed to save device info:", error);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
async getDeviceInfo() {
|
|
1552
|
+
try {
|
|
1553
|
+
if (this.storage) {
|
|
1554
|
+
return this.storage.getStorageSync(this.DEVICE_INFO_KEY) || null;
|
|
1555
|
+
}
|
|
1556
|
+
return null;
|
|
1557
|
+
} catch (error) {
|
|
1558
|
+
console.error("Failed to get device info:", error);
|
|
1559
|
+
return null;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
async saveSessionId(sessionId) {
|
|
1563
|
+
try {
|
|
1564
|
+
if (this.storage) {
|
|
1565
|
+
this.storage.setStorageSync(this.SESSION_ID_KEY, sessionId);
|
|
1566
|
+
}
|
|
1567
|
+
} catch (error) {
|
|
1568
|
+
console.error("Failed to save session ID:", error);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
async getSessionId() {
|
|
1572
|
+
try {
|
|
1573
|
+
if (this.storage) {
|
|
1574
|
+
return this.storage.getStorageSync(this.SESSION_ID_KEY) || null;
|
|
1575
|
+
}
|
|
1576
|
+
return null;
|
|
1577
|
+
} catch (error) {
|
|
1578
|
+
console.error("Failed to get session ID:", error);
|
|
1579
|
+
return null;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
var MiniappNetworkAdapter = class {
|
|
1584
|
+
// 需要注入 Taro 的网络 API
|
|
1585
|
+
constructor(request, netInfo) {
|
|
1586
|
+
this.request = request;
|
|
1587
|
+
this.netInfo = netInfo;
|
|
1588
|
+
}
|
|
1589
|
+
async upload(url, events) {
|
|
1590
|
+
try {
|
|
1591
|
+
if (!this.request) {
|
|
1592
|
+
throw new Error("Request module not provided");
|
|
1593
|
+
}
|
|
1594
|
+
const response = await this.request.request({
|
|
1595
|
+
url,
|
|
1596
|
+
method: "POST",
|
|
1597
|
+
data: {
|
|
1598
|
+
events,
|
|
1599
|
+
timestamp: Date.now()
|
|
1600
|
+
},
|
|
1601
|
+
header: {
|
|
1602
|
+
"Content-Type": "application/json"
|
|
1603
|
+
}
|
|
1604
|
+
});
|
|
1605
|
+
if (response.statusCode === 200) {
|
|
1606
|
+
return {
|
|
1607
|
+
success: true,
|
|
1608
|
+
message: response.data.message,
|
|
1609
|
+
code: response.statusCode
|
|
1610
|
+
};
|
|
1611
|
+
} else {
|
|
1612
|
+
return {
|
|
1613
|
+
success: false,
|
|
1614
|
+
message: `HTTP ${response.statusCode}`,
|
|
1615
|
+
code: response.statusCode
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
} catch (error) {
|
|
1619
|
+
return {
|
|
1620
|
+
success: false,
|
|
1621
|
+
message: error instanceof Error ? error.message : "Network error",
|
|
1622
|
+
code: 0
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
async isOnline() {
|
|
1627
|
+
try {
|
|
1628
|
+
if (this.netInfo) {
|
|
1629
|
+
const { networkType } = await this.netInfo.getNetworkType();
|
|
1630
|
+
return networkType !== "none";
|
|
1631
|
+
}
|
|
1632
|
+
return true;
|
|
1633
|
+
} catch (error) {
|
|
1634
|
+
return true;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
};
|
|
1638
|
+
var MiniappDeviceAdapter = class {
|
|
1639
|
+
// 需要注入 Taro 的系统信息 API
|
|
1640
|
+
constructor(systemInfo) {
|
|
1641
|
+
this.systemInfo = systemInfo;
|
|
1642
|
+
}
|
|
1643
|
+
async getDeviceInfo() {
|
|
1644
|
+
try {
|
|
1645
|
+
if (this.systemInfo) {
|
|
1646
|
+
const info = this.systemInfo.getSystemInfoSync();
|
|
1647
|
+
return {
|
|
1648
|
+
device_id: await this.generateDeviceId(),
|
|
1649
|
+
device_model: info.model || "unknown",
|
|
1650
|
+
device_brand: info.brand || "unknown",
|
|
1651
|
+
os_name: info.platform || "unknown",
|
|
1652
|
+
os_version: info.system || "unknown",
|
|
1653
|
+
screen_width: info.screenWidth || 0,
|
|
1654
|
+
screen_height: info.screenHeight || 0,
|
|
1655
|
+
language: info.language || "zh_CN",
|
|
1656
|
+
timezone: "Asia/Shanghai",
|
|
1657
|
+
network_type: info.networkType
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
return this.getDefaultDeviceInfo();
|
|
1661
|
+
} catch (error) {
|
|
1662
|
+
console.error("Failed to get device info:", error);
|
|
1663
|
+
return this.getDefaultDeviceInfo();
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
async generateDeviceId() {
|
|
1667
|
+
const timestamp = Date.now();
|
|
1668
|
+
const random = Math.random().toString(36).substring(2, 15);
|
|
1669
|
+
return `miniapp_${timestamp}_${random}`;
|
|
1670
|
+
}
|
|
1671
|
+
getDefaultDeviceInfo() {
|
|
1672
|
+
return {
|
|
1673
|
+
device_id: `miniapp_${Date.now()}`,
|
|
1674
|
+
os_name: "wechat",
|
|
1675
|
+
os_version: "unknown",
|
|
1676
|
+
screen_width: 0,
|
|
1677
|
+
screen_height: 0,
|
|
1678
|
+
language: "zh_CN",
|
|
1679
|
+
timezone: "Asia/Shanghai"
|
|
1680
|
+
};
|
|
1681
|
+
}
|
|
1682
|
+
};
|
|
1683
|
+
|
|
1684
|
+
// src/analytics/adapters/desktop.ts
|
|
1685
|
+
var DesktopStorageAdapter = class {
|
|
1686
|
+
constructor() {
|
|
1687
|
+
this.EVENTS_KEY = "analytics:events";
|
|
1688
|
+
this.DEVICE_INFO_KEY = "analytics:device_info";
|
|
1689
|
+
this.SESSION_ID_KEY = "analytics:session_id";
|
|
1690
|
+
}
|
|
1691
|
+
async saveEvents(events) {
|
|
1692
|
+
try {
|
|
1693
|
+
if (typeof window !== "undefined") {
|
|
1694
|
+
localStorage.setItem(this.EVENTS_KEY, JSON.stringify(events));
|
|
1695
|
+
}
|
|
1696
|
+
} catch (error) {
|
|
1697
|
+
console.error("Failed to save events:", error);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
async getEvents() {
|
|
1701
|
+
try {
|
|
1702
|
+
if (typeof window !== "undefined") {
|
|
1703
|
+
const data = localStorage.getItem(this.EVENTS_KEY);
|
|
1704
|
+
return data ? JSON.parse(data) : [];
|
|
1705
|
+
}
|
|
1706
|
+
return [];
|
|
1707
|
+
} catch (error) {
|
|
1708
|
+
console.error("Failed to get events:", error);
|
|
1709
|
+
return [];
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
async clearEvents() {
|
|
1713
|
+
try {
|
|
1714
|
+
if (typeof window !== "undefined") {
|
|
1715
|
+
localStorage.removeItem(this.EVENTS_KEY);
|
|
1716
|
+
}
|
|
1717
|
+
} catch (error) {
|
|
1718
|
+
console.error("Failed to clear events:", error);
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
async saveDeviceInfo(info) {
|
|
1722
|
+
try {
|
|
1723
|
+
if (typeof window !== "undefined") {
|
|
1724
|
+
localStorage.setItem(this.DEVICE_INFO_KEY, JSON.stringify(info));
|
|
1725
|
+
}
|
|
1726
|
+
} catch (error) {
|
|
1727
|
+
console.error("Failed to save device info:", error);
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
async getDeviceInfo() {
|
|
1731
|
+
try {
|
|
1732
|
+
if (typeof window !== "undefined") {
|
|
1733
|
+
const data = localStorage.getItem(this.DEVICE_INFO_KEY);
|
|
1734
|
+
return data ? JSON.parse(data) : null;
|
|
1735
|
+
}
|
|
1736
|
+
return null;
|
|
1737
|
+
} catch (error) {
|
|
1738
|
+
console.error("Failed to get device info:", error);
|
|
1739
|
+
return null;
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
async saveSessionId(sessionId) {
|
|
1743
|
+
try {
|
|
1744
|
+
if (typeof window !== "undefined") {
|
|
1745
|
+
localStorage.setItem(this.SESSION_ID_KEY, sessionId);
|
|
1746
|
+
}
|
|
1747
|
+
} catch (error) {
|
|
1748
|
+
console.error("Failed to save session ID:", error);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
async getSessionId() {
|
|
1752
|
+
try {
|
|
1753
|
+
if (typeof window !== "undefined") {
|
|
1754
|
+
return localStorage.getItem(this.SESSION_ID_KEY);
|
|
1755
|
+
}
|
|
1756
|
+
return null;
|
|
1757
|
+
} catch (error) {
|
|
1758
|
+
console.error("Failed to get session ID:", error);
|
|
1759
|
+
return null;
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
};
|
|
1763
|
+
var DesktopNetworkAdapter = class {
|
|
1764
|
+
async upload(url, events) {
|
|
1765
|
+
try {
|
|
1766
|
+
const response = await fetch(url, {
|
|
1767
|
+
method: "POST",
|
|
1768
|
+
headers: {
|
|
1769
|
+
"Content-Type": "application/json"
|
|
1770
|
+
},
|
|
1771
|
+
body: JSON.stringify({
|
|
1772
|
+
events,
|
|
1773
|
+
timestamp: Date.now()
|
|
1774
|
+
})
|
|
1775
|
+
});
|
|
1776
|
+
if (response.ok) {
|
|
1777
|
+
const data = await response.json();
|
|
1778
|
+
return {
|
|
1779
|
+
success: true,
|
|
1780
|
+
message: data.message,
|
|
1781
|
+
code: response.status
|
|
1782
|
+
};
|
|
1783
|
+
} else {
|
|
1784
|
+
return {
|
|
1785
|
+
success: false,
|
|
1786
|
+
message: `HTTP ${response.status}`,
|
|
1787
|
+
code: response.status
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
} catch (error) {
|
|
1791
|
+
return {
|
|
1792
|
+
success: false,
|
|
1793
|
+
message: error instanceof Error ? error.message : "Network error",
|
|
1794
|
+
code: 0
|
|
1795
|
+
};
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
async isOnline() {
|
|
1799
|
+
if (typeof navigator !== "undefined" && "onLine" in navigator) {
|
|
1800
|
+
return navigator.onLine;
|
|
1801
|
+
}
|
|
1802
|
+
return true;
|
|
1803
|
+
}
|
|
1804
|
+
};
|
|
1805
|
+
var DesktopDeviceAdapter = class {
|
|
1806
|
+
async getDeviceInfo() {
|
|
1807
|
+
return {
|
|
1808
|
+
device_id: await this.generateDeviceId(),
|
|
1809
|
+
os_name: this.getOSName(),
|
|
1810
|
+
os_version: this.getOSVersion(),
|
|
1811
|
+
screen_width: typeof window !== "undefined" ? window.screen.width : 0,
|
|
1812
|
+
screen_height: typeof window !== "undefined" ? window.screen.height : 0,
|
|
1813
|
+
language: typeof navigator !== "undefined" ? navigator.language : "en",
|
|
1814
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
1815
|
+
device_model: "Desktop",
|
|
1816
|
+
device_brand: "Electron"
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1819
|
+
async generateDeviceId() {
|
|
1820
|
+
if (typeof window !== "undefined") {
|
|
1821
|
+
let deviceId = localStorage.getItem("analytics:device_id");
|
|
1822
|
+
if (!deviceId) {
|
|
1823
|
+
deviceId = `desktop_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
1824
|
+
localStorage.setItem("analytics:device_id", deviceId);
|
|
1825
|
+
}
|
|
1826
|
+
return deviceId;
|
|
1827
|
+
}
|
|
1828
|
+
return `desktop_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
1829
|
+
}
|
|
1830
|
+
getOSName() {
|
|
1831
|
+
if (typeof navigator === "undefined") return "unknown";
|
|
1832
|
+
const platform = navigator.platform.toLowerCase();
|
|
1833
|
+
if (platform.indexOf("win") !== -1) return "Windows";
|
|
1834
|
+
if (platform.indexOf("mac") !== -1) return "MacOS";
|
|
1835
|
+
if (platform.indexOf("linux") !== -1) return "Linux";
|
|
1836
|
+
return "unknown";
|
|
1837
|
+
}
|
|
1838
|
+
getOSVersion() {
|
|
1839
|
+
if (typeof navigator === "undefined") return "unknown";
|
|
1840
|
+
return navigator.userAgent;
|
|
1841
|
+
}
|
|
1842
|
+
};
|
|
1843
|
+
|
|
1135
1844
|
// src/analytics/index.ts
|
|
1136
1845
|
var ANALYTICS_VERSION = "1.0.0";
|
|
1137
1846
|
|
|
1138
|
-
export { ANALYTICS_VERSION, Analytics, CatchError, EventPriority, EventQueue, EventType, Track, TrackClick, TrackPerformance, Uploader, createDesktopConfig, createMiniappConfig, createMobileConfig, createWebConfig, debounce, deepClone, formatEvent, formatTimestamp, generateUniqueId, getBatchSize, getCurrentPageTitle, getCurrentPageUrl, getEventSize, getGlobalAnalytics, getPageDuration, getReferrer, isDevelopment, isMobile, mergeEventProperties, safeParse, safeStringify, sanitizeEvent, setGlobalAnalytics, throttle, useAnalytics, useAutoTracking, useErrorTracking, usePageDuration, usePageView, usePerformanceTracking, useTrackClick, useTrackEvent, validateEvent, validateEvents };
|
|
1847
|
+
export { ANALYTICS_VERSION, Analytics, CatchError, DesktopDeviceAdapter, DesktopNetworkAdapter, DesktopStorageAdapter, EventPriority, EventQueue, EventType, MiniappDeviceAdapter, MiniappNetworkAdapter, MiniappStorageAdapter, MobileDeviceAdapter, MobileNetworkAdapter, MobileStorageAdapter, Track, TrackClick, TrackPerformance, Uploader, WebDeviceAdapter, WebNetworkAdapter, WebStorageAdapter, createAnalytics, createDesktopConfig, createMiniappConfig, createMobileConfig, createWebConfig, debounce, deepClone, formatEvent, formatTimestamp, generateUniqueId, getAllInstanceKeys, getAnalyticsInstance, getBatchSize, getCurrentPageTitle, getCurrentPageUrl, getEventSize, getGlobalAnalytics, getPageDuration, getReferrer, isAnalyticsInitialized, isDevelopment, isMobile, mergeEventProperties, resetAllAnalytics, resetAnalytics, safeParse, safeStringify, sanitizeEvent, setGlobalAnalytics, throttle, useAnalytics, useAutoTracking, useErrorTracking, usePageDuration, usePageView, usePerformanceTracking, useTrackClick, useTrackEvent, validateEvent, validateEvents, webAdapter };
|
|
1139
1848
|
//# sourceMappingURL=index.mjs.map
|
|
1140
1849
|
//# sourceMappingURL=index.mjs.map
|