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