keytops-game-framework 1.0.26 → 2.1.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/index.js CHANGED
@@ -881,44 +881,520 @@ Storage.created = false;
881
881
  */
882
882
  const storage = new Storage();
883
883
 
884
+ /**
885
+ * 通用计时器实现。
886
+ * 使用 setInterval 驱动 Timer 的内部更新循环。
887
+ */
888
+ class TimerImpl {
889
+ constructor() {
890
+ this._intervalMap = new WeakMap();
891
+ }
892
+ enable(timer) {
893
+ if (this._intervalMap.has(timer)) {
894
+ return;
895
+ }
896
+ const intervalId = setInterval(() => {
897
+ timer["_update"]();
898
+ }, 100);
899
+ this._intervalMap.set(timer, intervalId);
900
+ }
901
+ }
902
+
903
+ class MathUtils {
904
+ /**
905
+ * 随机
906
+ * @param min
907
+ * @param max
908
+ */
909
+ static random(min, max) {
910
+ this.seed = (this.seed * 9301 + 49297) % 233280;
911
+ let c = this.seed / (233280.0);
912
+ return min + c * (max - min);
913
+ }
914
+ /**
915
+ * 随机整数值
916
+ * @param min
917
+ * @param max
918
+ */
919
+ static randomInt(min, max) {
920
+ return Math.floor(this.random(min, max + 0.999));
921
+ }
922
+ /**
923
+ * 随机唯一稳定值
924
+ * @param min
925
+ * @param max
926
+ * @param clear 是否清除唯一记录
927
+ */
928
+ static randomOnlyInt(min, max, clear) {
929
+ if (clear) {
930
+ this.onlyMap.clear();
931
+ }
932
+ let value = this.randomInt(min, max);
933
+ let tryCount = (max - min) * 2;
934
+ let tryIndex = 0;
935
+ while (this.onlyMap.has(value)) {
936
+ value = this.randomInt(min, max);
937
+ if (tryIndex > tryCount) {
938
+ console.error("所有唯一值已取完");
939
+ return 0;
940
+ }
941
+ tryIndex++;
942
+ }
943
+ this.onlyMap.set(value, true);
944
+ return value;
945
+ }
946
+ /**
947
+ * 获取两点间的角度
948
+ * @param p1 点1
949
+ * @param p2 点2
950
+ */
951
+ static getAngle(p1, p2) {
952
+ return Math.atan((p2.y - p1.y) / (p2.x - p1.x));
953
+ }
954
+ /**
955
+ * 获取两点间的距离
956
+ * @param p1 点1
957
+ * @param p2 点2
958
+ */
959
+ static getDistance(p1, p2) {
960
+ return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
961
+ }
962
+ /**
963
+ * 将角度转为弧度
964
+ * @param angle 角度
965
+ */
966
+ static angleToRadian(angle) {
967
+ return angle * Math.PI / 180;
968
+ }
969
+ /**
970
+ * 求旋转后的点坐标
971
+ * @param angle 角度
972
+ * @param point 旋转前的坐标点
973
+ * @param result
974
+ */
975
+ static getRotationPoint(angle, pointOrDir, result) {
976
+ if (result == null) {
977
+ result = { x: 0, y: 0 };
978
+ }
979
+ //角度转弧度
980
+ angle = angle * (Math.PI / 180);
981
+ result.x = Math.cos(angle) * pointOrDir.x - Math.sin(angle) * pointOrDir.y;
982
+ result.y = Math.cos(angle) * pointOrDir.y + Math.sin(angle) * pointOrDir.x;
983
+ return result;
984
+ }
985
+ }
986
+ /**
987
+ * 随机种子
988
+ */
989
+ MathUtils.seed = 10;
990
+ /**
991
+ * 唯一记录
992
+ */
993
+ MathUtils.onlyMap = new Map();
994
+
995
+ class StringUtils {
996
+ static random(length, chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") {
997
+ var result = '';
998
+ for (var i = length; i > 0; --i) {
999
+ result += chars[Math.floor(Math.random() * chars.length)];
1000
+ }
1001
+ return result;
1002
+ }
1003
+ /**
1004
+ * 判断是否是远程资源
1005
+ * @param url
1006
+ * @returns
1007
+ */
1008
+ static isRemote(url) {
1009
+ if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0) {
1010
+ return true;
1011
+ }
1012
+ return false;
1013
+ }
1014
+ /**
1015
+ * 是否为空
1016
+ * @param str
1017
+ */
1018
+ static isEmpty(str) {
1019
+ if (str == null || str == undefined || str.length == 0) {
1020
+ return true;
1021
+ }
1022
+ return false;
1023
+ }
1024
+ /**
1025
+ * 替换全部字符串
1026
+ * @param string src 源串
1027
+ * @param string from_ch 被替换的字符
1028
+ * @param string to_ch 替换的字符
1029
+ *
1030
+ * @return string 结果字符串
1031
+ */
1032
+ static replaceAll(src, from_ch, to_ch) {
1033
+ let regExp = new RegExp(from_ch, "g");
1034
+ return src.replace(regExp, to_ch);
1035
+ }
1036
+ /**
1037
+ * 参数替换
1038
+ * @param str
1039
+ * @param rest
1040
+ *
1041
+ * @example
1042
+ *
1043
+ * var str:string = "here is some info '{0}' and {1}";
1044
+ * trace(StringUtil.substitute(str, 15.4, true));
1045
+ *
1046
+ * // this will output the following string:
1047
+ * // "here is some info '15.4' and true"
1048
+ */
1049
+ static format(str, ...rest) {
1050
+ if (str == null)
1051
+ return '';
1052
+ // Replace all of the parameters in the msg string.
1053
+ var len = rest.length;
1054
+ var args;
1055
+ if (len == 1 && rest[0] instanceof Array) {
1056
+ args = rest[0];
1057
+ len = args.length;
1058
+ }
1059
+ else {
1060
+ args = rest;
1061
+ }
1062
+ for (var i = 0; i < len; i++) {
1063
+ str = str.replace(new RegExp("\\{" + i + "\\}", "g"), args[i]);
1064
+ }
1065
+ return str;
1066
+ }
1067
+ /**
1068
+ *
1069
+ * 格式化数字
1070
+ * @param amount 目标数字
1071
+ * @param format 支持{1:"", 100:"百", 1000:"千", 10000:"万", 100000:"十万", 1000000:"百万", 10000000:"千万", 100000000:"亿", 1000000000000:"兆"}等
1072
+ * @returns
1073
+ */
1074
+ static formatNumber(amount, format) {
1075
+ if (!format || amount == 0) {
1076
+ return `${amount}`;
1077
+ }
1078
+ let formatKey = [];
1079
+ for (const key in format) {
1080
+ if (format.hasOwnProperty(key)) {
1081
+ formatKey.push(Number(key));
1082
+ }
1083
+ }
1084
+ if (!formatKey || formatKey.length == 0) {
1085
+ return `${amount}`;
1086
+ }
1087
+ formatKey.sort((a, b) => b - a);
1088
+ let result = [];
1089
+ let total = amount;
1090
+ for (let i = 0; i < formatKey.length; i++) {
1091
+ const key = formatKey[i];
1092
+ let count = Math.floor(Math.abs(total / key)) * (total / Math.abs(total));
1093
+ if (count == 0) {
1094
+ continue;
1095
+ }
1096
+ total = total % key;
1097
+ result.push(`${count}${format[key]}`);
1098
+ }
1099
+ return result.length ? result.join("") : `${amount}`;
1100
+ }
1101
+ /**
1102
+ * 带自动补全的秒数格式。
1103
+ * @param second 秒数
1104
+ * @param format 格式化文本
1105
+ * @param pad 填充文本,默认为“0”
1106
+ * @example
1107
+ * formatSecond(86400, "ddd天hh小时mm分ss秒")=>"001天00小时00分00秒"
1108
+ * formatSecond(86400, "dd天hh小时mm分ss秒")=>"01天00小时00分00秒"
1109
+ * formatSecond(86400, "hh小时mm分ss秒")=>"24小时00分00秒"
1110
+ * formatSecond(86400, "mm分ss秒")=>"1440分00秒"
1111
+ * @returns
1112
+ */
1113
+ static formatSecond(second, format, pad = "0") {
1114
+ const formatArr = [
1115
+ { unit: 86400, regExp: /D{2,}/i },
1116
+ { unit: 3600, regExp: /H{1,2}/i },
1117
+ { unit: 60, regExp: /m{1,2}/i },
1118
+ { unit: 1, regExp: /s{1,2}/i },
1119
+ ];
1120
+ for (let i = 0; i < formatArr.length; i++) {
1121
+ const element = formatArr[i];
1122
+ let match = element.regExp.exec(format);
1123
+ if (match) {
1124
+ format = format.replace(element.regExp, Math.floor(second / element.unit).toFixed(0).padStart(match[0].length, pad));
1125
+ second = second % element.unit;
1126
+ }
1127
+ }
1128
+ return format;
1129
+ }
1130
+ /**
1131
+ * 带自动补全的时间戳格式化
1132
+ * @param milliseconds
1133
+ * @param format
1134
+ * @param pad 填充文本,默认为“0”
1135
+ * @returns
1136
+ */
1137
+ static formatTimestamp(milliseconds, format, pad = "0") {
1138
+ let date = new Date(milliseconds);
1139
+ date.getHours();
1140
+ const formatArr = [
1141
+ { r: /Y{4}/, to: date.getFullYear() },
1142
+ { r: /M{1,2}/, to: date.getMonth() + 1 },
1143
+ { r: /D{1,2}/, to: date.getDate() },
1144
+ { r: /H{1,2}/, to: date.getHours() },
1145
+ { r: /m{1,2}/, to: date.getMinutes() },
1146
+ { r: /s{1,2}/, to: date.getSeconds() },
1147
+ ];
1148
+ for (let i = 0; i < formatArr.length; i++) {
1149
+ const element = formatArr[i];
1150
+ let match = element.r.exec(format);
1151
+ if (match) {
1152
+ format = format.replace(element.r, element.to.toString().padStart(match[0].length, "0"));
1153
+ }
1154
+ }
1155
+ return format;
1156
+ }
1157
+ }
1158
+
1159
+ /**
1160
+ * 对象池
1161
+ */
1162
+ class Pool {
1163
+ constructor(clazz, maxCount) {
1164
+ /**池中闲置对象 */
1165
+ this._cacheStack = new Array();
1166
+ /**正在使用的对象 */
1167
+ this._usingArray = new Array();
1168
+ /**池中对象最大数 */
1169
+ this._maxCount = 0;
1170
+ this._class = clazz;
1171
+ if (!this._class) {
1172
+ throw new Error("构造函数不能为空!");
1173
+ }
1174
+ this._maxCount = maxCount == undefined ? Number.MAX_SAFE_INTEGER : maxCount;
1175
+ }
1176
+ /**
1177
+ * 在池中的对象
1178
+ */
1179
+ get count() {
1180
+ return this._cacheStack.length;
1181
+ }
1182
+ /**
1183
+ * 使用中的数量
1184
+ */
1185
+ get usingCount() {
1186
+ return this._usingArray.length;
1187
+ }
1188
+ /**
1189
+ * 分配
1190
+ * @returns
1191
+ */
1192
+ allocate(createData) {
1193
+ if (this.count + this.usingCount < this._maxCount) {
1194
+ let element = this._cacheStack.length > 0 ? this._cacheStack.pop() : (typeof createData === 'function' ? createData() : new this._class(createData));
1195
+ this._usingArray.push(element);
1196
+ return element;
1197
+ }
1198
+ throw new Error("对象池最大数量超出:" + this._maxCount);
1199
+ }
1200
+ /**
1201
+ * 回收到池中
1202
+ * @param value
1203
+ * @returns
1204
+ */
1205
+ recover(value) {
1206
+ if (this._cacheStack.indexOf(value) > -1) {
1207
+ throw new Error("重复回收!");
1208
+ }
1209
+ let index = this._usingArray.indexOf(value);
1210
+ if (index < 0) {
1211
+ throw new Error("对象不属于改对象池!");
1212
+ }
1213
+ //重置
1214
+ value.reset();
1215
+ this._usingArray.splice(index, 1);
1216
+ this._cacheStack.push(value);
1217
+ }
1218
+ /**
1219
+ * 批量回收
1220
+ * @param list
1221
+ */
1222
+ recoverList(list) {
1223
+ for (let index = 0; index < list.length; index++) {
1224
+ const element = list[index];
1225
+ this.recover(element);
1226
+ }
1227
+ }
1228
+ /**
1229
+ * 将所有使用中的对象都回收到池中
1230
+ */
1231
+ recoverAll() {
1232
+ for (let index = 0; index < this._usingArray.length; index++) {
1233
+ const element = this._usingArray[index];
1234
+ this.recover(element);
1235
+ }
1236
+ }
1237
+ destroy() {
1238
+ this.recoverAll();
1239
+ for (let index = 0; index < this._cacheStack.length; index++) {
1240
+ const element = this._cacheStack[index];
1241
+ element.destroy();
1242
+ }
1243
+ this._cacheStack.length = 0;
1244
+ this._cacheStack = null;
1245
+ this._usingArray.length = 0;
1246
+ this._usingArray = null;
1247
+ }
1248
+ }
1249
+
1250
+ /**
1251
+ * <p><code>Handler</code> 是事件处理器类。</p>
1252
+ * <p>推荐使用 Handler.create() 方法从对象池创建,减少对象创建消耗。创建的 Handler 对象不再使用后,可以使用 Handler.recover() 将其回收到对象池,回收后不要再使用此对象,否则会导致不可预料的错误。</p>
1253
+ * <p><b>注意:</b>由于鼠标事件也用本对象池,不正确的回收及调用,可能会影响鼠标事件的执行。</p>
1254
+ */
1255
+ class Handler {
1256
+ /**
1257
+ * 根据指定的属性值,创建一个 <code>Handler</code> 类的实例。
1258
+ * @param caller 执行域。
1259
+ * @param method 处理函数。
1260
+ * @param args 函数参数。
1261
+ * @param once 是否只执行一次。
1262
+ */
1263
+ constructor(caller = null, method = null, args = null, once = false) {
1264
+ /** 表示是否只执行一次。如果为true,回调后执行recover()进行回收,回收后会被再利用,默认为false 。*/
1265
+ this.once = false;
1266
+ /**@private */
1267
+ this._id = 0;
1268
+ this.setTo(caller, method, args, once);
1269
+ }
1270
+ /**
1271
+ * 设置此对象的指定属性值。
1272
+ * @param caller 执行域(this)。
1273
+ * @param method 回调方法。
1274
+ * @param args 携带的参数。
1275
+ * @param once 是否只执行一次,如果为true,执行后执行recover()进行回收。
1276
+ * @return 返回 handler 本身。
1277
+ */
1278
+ setTo(caller, method, args, once = false) {
1279
+ this._id = Handler._gid++;
1280
+ this.caller = caller;
1281
+ this.method = method;
1282
+ this.args = args;
1283
+ this.once = once;
1284
+ return this;
1285
+ }
1286
+ /**
1287
+ * 执行处理器。
1288
+ */
1289
+ run() {
1290
+ if (this.method == null)
1291
+ return null;
1292
+ var id = this._id;
1293
+ var result = this.method.apply(this.caller, this.args);
1294
+ this._id === id && this.once && this.recover();
1295
+ return result;
1296
+ }
1297
+ /**
1298
+ * 执行处理器,并携带额外数据。
1299
+ * @param data 附加的回调数据,可以是单数据或者Array(作为多参)。
1300
+ */
1301
+ runWith(data) {
1302
+ if (this.method == null)
1303
+ return null;
1304
+ var id = this._id;
1305
+ if (data == null)
1306
+ var result = this.method.apply(this.caller, this.args);
1307
+ else if (!this.args && !data.unshift)
1308
+ result = this.method.call(this.caller, data);
1309
+ else if (this.args)
1310
+ result = this.method.apply(this.caller, this.args.concat(data));
1311
+ else
1312
+ result = this.method.apply(this.caller, data);
1313
+ this._id === id && this.once && this.recover();
1314
+ return result;
1315
+ }
1316
+ /**
1317
+ * 清理对象引用。
1318
+ */
1319
+ clear() {
1320
+ this.caller = null;
1321
+ this.method = null;
1322
+ this.args = null;
1323
+ return this;
1324
+ }
1325
+ reset() {
1326
+ this.clear();
1327
+ }
1328
+ destroy() {
1329
+ this.clear();
1330
+ }
1331
+ /**
1332
+ * 清理并回收到 Handler 对象池内。
1333
+ */
1334
+ recover() {
1335
+ if (this._id > 0) {
1336
+ this._id = 0;
1337
+ Handler._pool.recover(this);
1338
+ }
1339
+ }
1340
+ equal(value) {
1341
+ return value === this;
1342
+ }
1343
+ /**
1344
+ * 从对象池内创建一个Handler,默认会执行一次并立即回收,如果不需要自动回收,设置once参数为false。
1345
+ * @param caller 执行域(this)。
1346
+ * @param method 回调方法。
1347
+ * @param args 携带的参数。
1348
+ * @param once 是否只执行一次,如果为true,回调后执行recover()进行回收,默认为true。
1349
+ * @return 返回创建的handler实例。
1350
+ */
1351
+ static create(caller, method, args = null, once = true) {
1352
+ return Handler._pool.allocate().setTo(caller, method, args, once);
1353
+ }
1354
+ }
1355
+ /**@private handler对象池*/
1356
+ Handler._pool = new Pool(Handler);
1357
+ /**@private */
1358
+ Handler._gid = 1;
1359
+
884
1360
  var InternalProperty;
885
1361
  (function (InternalProperty) {
886
1362
  /**设备系统版本 */
887
- InternalProperty["DEVICE_SYSTEM"] = "_ds_";
1363
+ InternalProperty["DEVICE_SYSTEM"] = "device_system";
888
1364
  /**设备操作系统类型 */
889
- InternalProperty["DEVICE_PLATFORM"] = "_dp_";
1365
+ InternalProperty["DEVICE_PLATFORM"] = "device_platform";
890
1366
  /**设备手机品牌 */
891
- InternalProperty["DEVICE_BRAND"] = "_db_";
1367
+ InternalProperty["DEVICE_BRAND"] = "device_brand";
892
1368
  /**设备手机型号 */
893
- InternalProperty["DEVICE_MODEL"] = "_dm_";
1369
+ InternalProperty["DEVICE_MODEL"] = "device_model";
894
1370
  /**宿主名称 */
895
- InternalProperty["HOST_NAME"] = "_hn_";
1371
+ InternalProperty["HOST_NAME"] = "host_name";
896
1372
  /**宿主版本 */
897
- InternalProperty["HOST_VERSION"] = "_hv_";
1373
+ InternalProperty["HOST_VERSION"] = "host_version";
898
1374
  /**启动时间 */
899
- InternalProperty["LAUNCH_TIME"] = "_lt_";
1375
+ InternalProperty["LAUNCH_TIME"] = "launch_time";
900
1376
  /**启动次数 */
901
- InternalProperty["LAUNCH_TIMES"] = "_lts_";
1377
+ InternalProperty["LAUNCH_TIMES"] = "launch_times";
902
1378
  /**安装时间 */
903
- InternalProperty["INSTALL_TIME"] = "_it_";
1379
+ InternalProperty["INSTALL_TIME"] = "install_time";
904
1380
  /**app运载(安装)时长 */
905
- InternalProperty["DURATION_OF_INSTALL"] = "_doi_";
1381
+ InternalProperty["DURATION_OF_INSTALL"] = "duration_of_install";
906
1382
  /**app运行(启动)时长 */
907
- InternalProperty["DURATION_OF_LAUNCH"] = "_dol_";
1383
+ InternalProperty["DURATION_OF_LAUNCH"] = "duration_of_launch";
908
1384
  /**累积登录天数 */
909
- InternalProperty["LOGIN_DAYS"] = "_lds_";
1385
+ InternalProperty["LOGIN_DAYS"] = "login_days";
910
1386
  /**安装来源type */
911
- InternalProperty["INSTALL_SCENE"] = "_is_";
1387
+ InternalProperty["INSTALL_SCENE"] = "install_scene";
912
1388
  /**安装来源source */
913
- InternalProperty["INSTALL_CHANNEL"] = "_ic_";
1389
+ InternalProperty["INSTALL_CHANNEL"] = "install_channel";
914
1390
  /**启动来源场景 */
915
- InternalProperty["LAUNCH_SCENE"] = "_ls_";
1391
+ InternalProperty["LAUNCH_SCENE"] = "launch_scene";
916
1392
  /**启动来源渠道 */
917
- InternalProperty["LAUNCH_CHANNEL"] = "_lc_";
1393
+ InternalProperty["LAUNCH_CHANNEL"] = "launch_channel";
918
1394
  /**事件计时时长 */
919
- InternalProperty["DURATION"] = "_dt_";
1395
+ InternalProperty["DURATION"] = "duration";
920
1396
  /**游戏版本 */
921
- InternalProperty["APP_VERSION"] = "_av_";
1397
+ InternalProperty["APP_VERSION"] = "app_version";
922
1398
  })(InternalProperty || (InternalProperty = {}));
923
1399
  class EmptyAnalyticsSender {
924
1400
  /**
@@ -940,7 +1416,10 @@ class EmptyAnalyticsSender {
940
1416
  }
941
1417
  return true;
942
1418
  }
943
- send(eventName, data) {
1419
+ mapEvent(eventName, eventData) {
1420
+ return { eventName, data: Object.assign({}, eventData) };
1421
+ }
1422
+ send(eventName, eventData, userProperties) {
944
1423
  return __awaiter(this, void 0, void 0, function* () {
945
1424
  });
946
1425
  }
@@ -955,6 +1434,8 @@ class AnalyticsAble {
955
1434
  this._debugMode = false;
956
1435
  this._senderList = [];
957
1436
  this._dynamicCalls = [];
1437
+ this._userId = null;
1438
+ this._hasSetUserId = false;
958
1439
  }
959
1440
  get inited() { return this._inited; }
960
1441
  /**
@@ -974,8 +1455,14 @@ class AnalyticsAble {
974
1455
  for (let i = 0; i < senders.length; i++) {
975
1456
  const sender = senders[i];
976
1457
  this._senderList.push(sender);
1458
+ if (this._hasSetUserId && typeof sender.setUserId === "function") {
1459
+ sender.setUserId(this._userId);
1460
+ }
977
1461
  }
978
1462
  }
1463
+ _getUserProperties() {
1464
+ return Object.assign({}, this._userOnceProperties || {}, this._userAddProperties || {}, this._userProperties || {});
1465
+ }
979
1466
  /**
980
1467
  * 设置排除
981
1468
  * @param excludeEvents 排除事件名称或者名称列表。
@@ -995,11 +1482,11 @@ class AnalyticsAble {
995
1482
  }
996
1483
  }
997
1484
  _onAppShow() {
998
- this.time("app_hide");
999
- this.report("app_show", publisher.publisher.enterOptions.getAllOption());
1485
+ this.time("app.hide");
1486
+ this.report("app.show", publisher.publisher.enterOptions.getAllOption());
1000
1487
  }
1001
1488
  _onAppHide() {
1002
- this.report("app_hide");
1489
+ this.report("app.hide");
1003
1490
  }
1004
1491
  /**
1005
1492
  * 设置所有上报事件的基础属性
@@ -1081,6 +1568,19 @@ class AnalyticsAble {
1081
1568
  setDynamicProperties(dynamicCall) {
1082
1569
  this._dynamicCalls.push(dynamicCall);
1083
1570
  }
1571
+ /**
1572
+ * 设置平台用户标识。该值不会自动作为事件参数发送。
1573
+ */
1574
+ setUserId(userId) {
1575
+ this._userId = userId;
1576
+ this._hasSetUserId = true;
1577
+ for (let i = 0; i < this._senderList.length; i++) {
1578
+ const sender = this._senderList[i];
1579
+ if (typeof sender.setUserId === "function") {
1580
+ sender.setUserId(userId);
1581
+ }
1582
+ }
1583
+ }
1084
1584
  /**
1085
1585
  * 对于一般的用户属性,您可以调用 userSet 来进行设置。
1086
1586
  * 使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性,类型与传入属性的类型一致。
@@ -1177,12 +1677,12 @@ class AnalyticsAble {
1177
1677
  * @param error 错误信息
1178
1678
  */
1179
1679
  error(error) {
1180
- this.report("app_error", { error: error });
1680
+ this.report("app.error", { error: error });
1181
1681
  }
1182
1682
  /**
1183
1683
  * 开始事件计时
1184
1684
  * 如果您需要记录某个事件的持续时长,可以调用 timeEvent 来开始计时。
1185
- * 配置您想要计时的事件名称,当您上传该事件时,将会自动在您的事件属性中加入 _dt_ 这一属性来表示记录的时长,单位为秒。
1685
+ * 配置您想要计时的事件名称,当您上传该事件时,将会自动在您的事件属性中加入 duration 属性来表示记录的时长,单位为秒。
1186
1686
  * 需要注意的是,同一个事件名只能有一个在计时的任务。
1187
1687
  * @param eventName
1188
1688
  */
@@ -1223,9 +1723,6 @@ class AnalyticsAble {
1223
1723
  const call = this._dynamicCalls[i];
1224
1724
  this._copyToData(eventName, data, call());
1225
1725
  }
1226
- this._copyToData(eventName, data, this._userProperties);
1227
- this._copyToData(eventName, data, this._userAddProperties);
1228
- this._copyToData(eventName, data, this._userOnceProperties);
1229
1726
  this._copyToData(eventName, data, this._staticProperties);
1230
1727
  if (this._timeEvents && this._timeEvents.has(eventName)) {
1231
1728
  let timeInfo = this._timeEvents.get(eventName);
@@ -1261,13 +1758,174 @@ class AnalyticsAble {
1261
1758
  }
1262
1759
  _sendReport(eventName, data) {
1263
1760
  return __awaiter(this, void 0, void 0, function* () {
1264
- return Promise.all(this._senderList.map((sender) => {
1265
- return sender.send(eventName, data);
1761
+ const userProperties = this._getUserProperties();
1762
+ return Promise.all(this._senderList
1763
+ .filter((sender) => sender.sendAble(eventName))
1764
+ .map((sender) => {
1765
+ const mapped = sender.mapEvent(eventName, Object.assign({}, data));
1766
+ if (!sender.sendAble(mapped.eventName)) {
1767
+ return Promise.resolve();
1768
+ }
1769
+ return sender.send(mapped.eventName, Object.assign({}, mapped.data), Object.assign({}, userProperties));
1266
1770
  })).then();
1267
1771
  });
1268
1772
  }
1269
1773
  }
1270
1774
 
1775
+ /**
1776
+ * 框架内部统一使用的业务语义事件名。
1777
+ * Sender 负责将它们转换成统计平台实际接收的事件名和参数。
1778
+ */
1779
+ var AnalyticsBehavior;
1780
+ (function (AnalyticsBehavior) {
1781
+ AnalyticsBehavior["APP_LAUNCH"] = "app.launch";
1782
+ AnalyticsBehavior["APP_SHOW"] = "app.show";
1783
+ AnalyticsBehavior["APP_HIDE"] = "app.hide";
1784
+ AnalyticsBehavior["APP_ERROR"] = "app.error";
1785
+ AnalyticsBehavior["SESSION_LOGIN"] = "session.login";
1786
+ AnalyticsBehavior["LEVEL_START"] = "level.start";
1787
+ AnalyticsBehavior["LEVEL_END"] = "level.end";
1788
+ AnalyticsBehavior["LEVEL_PAUSE"] = "level.pause";
1789
+ AnalyticsBehavior["LEVEL_TIMEOUT"] = "level.timeout";
1790
+ AnalyticsBehavior["LEVEL_ITEM_USE"] = "level.item_use";
1791
+ AnalyticsBehavior["AD_LIFECYCLE"] = "ad.lifecycle";
1792
+ AnalyticsBehavior["AD_IMPRESSION"] = "ad.impression";
1793
+ AnalyticsBehavior["SOCIAL_SHARE"] = "social.share";
1794
+ AnalyticsBehavior["SOCIAL_SUBSCRIBE_SHOW"] = "social.subscribe_show";
1795
+ AnalyticsBehavior["SOCIAL_SUBSCRIBE"] = "social.subscribe";
1796
+ AnalyticsBehavior["TUTORIAL_BEGIN"] = "tutorial.begin";
1797
+ AnalyticsBehavior["TUTORIAL_COMPLETE"] = "tutorial.complete";
1798
+ AnalyticsBehavior["TUTORIAL_SKIP"] = "tutorial.skip";
1799
+ AnalyticsBehavior["PAY_BEGIN"] = "pay.begin";
1800
+ AnalyticsBehavior["PAY_PURCHASE"] = "pay.purchase";
1801
+ AnalyticsBehavior["PAY_PENDING"] = "pay.pending";
1802
+ AnalyticsBehavior["PAY_CANCEL"] = "pay.cancel";
1803
+ AnalyticsBehavior["PAY_FAIL"] = "pay.fail";
1804
+ })(AnalyticsBehavior || (AnalyticsBehavior = {}));
1805
+ const LEVEL_RESULT_EVENT = {
1806
+ success: "lv_success",
1807
+ fail: "lv_fail",
1808
+ leave: "lv_leave",
1809
+ skip: "lv_skip",
1810
+ revive: "lv_revive",
1811
+ break: "lv_break",
1812
+ retry: "lv_retry",
1813
+ };
1814
+ const SHARE_PHASE_MESSAGE = {
1815
+ begin: "发起",
1816
+ success: "成功",
1817
+ fail: "失败",
1818
+ };
1819
+ function move(data, source, target) {
1820
+ if (data[source] !== undefined) {
1821
+ data[target] = data[source];
1822
+ delete data[source];
1823
+ }
1824
+ }
1825
+ /**
1826
+ * Keytops/Ali 当前服务端仍使用的物理协议。
1827
+ * 兼容逻辑集中在 Sender 边界,业务层无需继续依赖旧事件字符串。
1828
+ */
1829
+ function mapCanonicalEventToLegacy(eventName, eventData) {
1830
+ const data = Object.assign({}, eventData);
1831
+ let mappedName = eventName;
1832
+ switch (eventName) {
1833
+ case AnalyticsBehavior.APP_LAUNCH:
1834
+ case AnalyticsBehavior.APP_SHOW:
1835
+ case AnalyticsBehavior.APP_HIDE:
1836
+ case AnalyticsBehavior.APP_ERROR:
1837
+ case AnalyticsBehavior.SESSION_LOGIN:
1838
+ mappedName = eventName.replace(".", "_");
1839
+ if (eventName === AnalyticsBehavior.SESSION_LOGIN) {
1840
+ mappedName = "login";
1841
+ move(data, "options", "msg");
1842
+ }
1843
+ break;
1844
+ case AnalyticsBehavior.LEVEL_START:
1845
+ mappedName = "lv_enter";
1846
+ break;
1847
+ case AnalyticsBehavior.LEVEL_END:
1848
+ mappedName = LEVEL_RESULT_EVENT[String(data.result || "")] || "lv_leave";
1849
+ delete data.result;
1850
+ break;
1851
+ case AnalyticsBehavior.LEVEL_PAUSE:
1852
+ mappedName = "lv_leave";
1853
+ break;
1854
+ case AnalyticsBehavior.LEVEL_TIMEOUT:
1855
+ mappedName = "lv_timeout";
1856
+ break;
1857
+ case AnalyticsBehavior.LEVEL_ITEM_USE:
1858
+ mappedName = "lv_item";
1859
+ break;
1860
+ case AnalyticsBehavior.AD_LIFECYCLE:
1861
+ case AnalyticsBehavior.AD_IMPRESSION:
1862
+ mappedName = "ad";
1863
+ move(data, "adType", "_adtype");
1864
+ move(data, "lifecycle", "_adevent");
1865
+ move(data, "message", "msg");
1866
+ delete data.group;
1867
+ break;
1868
+ case AnalyticsBehavior.SOCIAL_SHARE:
1869
+ mappedName = "share";
1870
+ if (data.itemId !== undefined && data.name === undefined) {
1871
+ data.name = data.itemId;
1872
+ }
1873
+ if (data.phase !== undefined) {
1874
+ data.msg = SHARE_PHASE_MESSAGE[String(data.phase)] || String(data.phase);
1875
+ }
1876
+ break;
1877
+ case AnalyticsBehavior.SOCIAL_SUBSCRIBE_SHOW:
1878
+ mappedName = "subscribe_show";
1879
+ break;
1880
+ case AnalyticsBehavior.SOCIAL_SUBSCRIBE:
1881
+ mappedName = "subscribe";
1882
+ break;
1883
+ case AnalyticsBehavior.TUTORIAL_BEGIN:
1884
+ case AnalyticsBehavior.TUTORIAL_COMPLETE:
1885
+ case AnalyticsBehavior.TUTORIAL_SKIP:
1886
+ case AnalyticsBehavior.PAY_BEGIN:
1887
+ case AnalyticsBehavior.PAY_PURCHASE:
1888
+ case AnalyticsBehavior.PAY_PENDING:
1889
+ case AnalyticsBehavior.PAY_CANCEL:
1890
+ case AnalyticsBehavior.PAY_FAIL:
1891
+ mappedName = eventName.replace(".", "_");
1892
+ break;
1893
+ }
1894
+ if (eventName === AnalyticsBehavior.LEVEL_START ||
1895
+ eventName === AnalyticsBehavior.LEVEL_END ||
1896
+ eventName === AnalyticsBehavior.LEVEL_PAUSE ||
1897
+ eventName === AnalyticsBehavior.LEVEL_TIMEOUT ||
1898
+ eventName === AnalyticsBehavior.LEVEL_ITEM_USE) {
1899
+ move(data, "levelId", "id");
1900
+ move(data, "levelIndex", "index");
1901
+ move(data, "gameId", "type");
1902
+ move(data, "repeatCount", "code");
1903
+ move(data, "averageThinkTimeMs", "time");
1904
+ move(data, "itemName", "name");
1905
+ if (eventName === AnalyticsBehavior.LEVEL_TIMEOUT) {
1906
+ data.name = "超时";
1907
+ delete data.reason;
1908
+ }
1909
+ else if (eventName === AnalyticsBehavior.LEVEL_PAUSE) {
1910
+ data.name = "切出游戏";
1911
+ delete data.reason;
1912
+ }
1913
+ else {
1914
+ move(data, "reason", "name");
1915
+ }
1916
+ }
1917
+ return { eventName: mappedName, data };
1918
+ }
1919
+ /**
1920
+ * 小游戏平台通常不接受点号事件名,统一转换为下划线。
1921
+ */
1922
+ function mapCanonicalEventToFlatName(eventName, eventData) {
1923
+ return {
1924
+ eventName: eventName.replace(/\./g, "_"),
1925
+ data: Object.assign({}, eventData),
1926
+ };
1927
+ }
1928
+
1271
1929
  const ALI_ANALYTICS_EVENT_CACHE = "ALI_ANALYTICS_EVENT_CACHE";
1272
1930
  /**
1273
1931
  * 内部阿里云日志事件上报器
@@ -1362,16 +2020,21 @@ class ALiAnalyticsSender extends EmptyAnalyticsSender {
1362
2020
  return false;
1363
2021
  }
1364
2022
  }
1365
- send(eventName, data) {
2023
+ mapEvent(eventName, eventData) {
2024
+ return mapCanonicalEventToLegacy(eventName, eventData);
2025
+ }
2026
+ send(eventName, eventData, userProperties) {
1366
2027
  return __awaiter(this, void 0, void 0, function* () {
1367
- data['_event'] = eventName;
2028
+ const payload = eventData && typeof eventData === "object" && !Array.isArray(eventData)
2029
+ ? Object.assign(Object.assign({}, userProperties), eventData) : Object.assign({}, userProperties);
2030
+ payload['_event'] = eventName;
1368
2031
  let msg_data = {
1369
2032
  appid: publisher.appId,
1370
2033
  openid: storage.userId || publisher.login.openID || "",
1371
2034
  deviceid: App.deviceId,
1372
2035
  sessionid: App.sessionId,
1373
2036
  level: ++this._index,
1374
- data: JSON.stringify(data),
2037
+ data: JSON.stringify(payload),
1375
2038
  event: eventName,
1376
2039
  timestamp: this._config.timestampCall() || Date.now()
1377
2040
  };
@@ -1645,301 +2308,100 @@ var ADEvent;
1645
2308
  ADEvent[ADEvent["SHOW_FAIL"] = 5] = "SHOW_FAIL";
1646
2309
  ADEvent[ADEvent["CLOSE_BY_USER"] = 6] = "CLOSE_BY_USER";
1647
2310
  })(ADEvent || (ADEvent = {}));
1648
- class ADBehaviorReporter {
1649
- constructor(baseAble) {
1650
- this.baseAble = baseAble;
1651
- this._groupCount = {};
1652
- }
1653
- /**
1654
- * 重置单个模块的广告计数
1655
- * @param group 模块名称,默认为game
1656
- */
1657
- resetGroupCount(group = "game") {
1658
- this._groupCount[group] = 0;
1659
- }
1660
- /**
1661
- * 开始加载广告
1662
- * @param type 广告类型
1663
- * @param from 广告来源
1664
- * @param msg 广告失败原因
1665
- */
1666
- onStartLoad(type, from, msg) {
1667
- this.report(type, ADEvent.LOAD, from, msg);
1668
- }
1669
- /**
1670
- * 广告加载完成
1671
- * @param type 广告类型
1672
- * @param from 广告来源
1673
- */
1674
- onLoadComplete(type, from) {
1675
- this.report(type, ADEvent.LOAD_COMPLETE, from);
1676
- }
1677
- /**
1678
- * 广告加载失败
1679
- * @param type 广告类型
1680
- * @param from 广告来源
1681
- * @param msg 广告失败原因
1682
- */
1683
- onLoadFail(type, from, msg) {
1684
- this.report(type, ADEvent.LOAD_FAIL, from, msg);
1685
- }
1686
- /**
1687
- * 显示广告
1688
- * @param type 广告类型
1689
- * @param from 广告来源
1690
- */
1691
- onShow(type, from) {
1692
- this.report(type, ADEvent.SHOW, from);
1693
- }
1694
- /**
1695
- * 广告显示完成
1696
- * @param type 广告类型
1697
- * @param from 广告来源
1698
- */
1699
- onShowComplete(type, from) {
1700
- this.report(type, ADEvent.SHOW_COMPLETE, from);
1701
- }
1702
- /**
1703
- * 广告显示失败
1704
- * @param type 广告类型
1705
- * @param from 广告来源
1706
- * @param msg 广告失败原因
1707
- */
1708
- onShowFail(type, from, msg) {
1709
- this.report(type, ADEvent.SHOW_FAIL, from, msg);
1710
- }
1711
- /**
1712
- * 用户关闭广告
1713
- * @param type 广告类型
1714
- * @param from 广告来源
1715
- */
1716
- onCloseByUser(type, from) {
1717
- this.report(type, ADEvent.CLOSE_BY_USER, from);
1718
- }
1719
- /**
1720
- * 上报广告事件
1721
- * @param type 广告类型
1722
- * @param event 广告事件
1723
- * @param from 广告来源
1724
- * @param msg 广告失败原因
1725
- */
1726
- report(type, event, from, msg) {
1727
- from = from || {};
1728
- const group = from.group || "game";
1729
- from.group && delete from.group;
1730
- from._adtype = type;
1731
- from._adevent = event;
1732
- if (!this._groupCount[group]) {
1733
- this._groupCount[group] = 0;
1734
- }
1735
- from.count = event == ADEvent.SHOW_COMPLETE ? ++this._groupCount[group] : this._groupCount[group];
1736
- if (msg) {
1737
- from.msg = msg;
1738
- }
1739
- this.baseAble.report("ad", from);
1740
- }
1741
- }
1742
-
1743
- /**
1744
- * 对象池
1745
- */
1746
- class Pool {
1747
- constructor(clazz, maxCount) {
1748
- /**池中闲置对象 */
1749
- this._cacheStack = new Array();
1750
- /**正在使用的对象 */
1751
- this._usingArray = new Array();
1752
- /**池中对象最大数 */
1753
- this._maxCount = 0;
1754
- this._class = clazz;
1755
- if (!this._class) {
1756
- throw new Error("构造函数不能为空!");
1757
- }
1758
- this._maxCount = maxCount == undefined ? Number.MAX_SAFE_INTEGER : maxCount;
1759
- }
1760
- /**
1761
- * 在池中的对象
1762
- */
1763
- get count() {
1764
- return this._cacheStack.length;
1765
- }
1766
- /**
1767
- * 使用中的数量
1768
- */
1769
- get usingCount() {
1770
- return this._usingArray.length;
1771
- }
1772
- /**
1773
- * 分配
1774
- * @returns
1775
- */
1776
- allocate(createData) {
1777
- if (this.count + this.usingCount < this._maxCount) {
1778
- let element = this._cacheStack.length > 0 ? this._cacheStack.pop() : (typeof createData === 'function' ? createData() : new this._class(createData));
1779
- this._usingArray.push(element);
1780
- return element;
1781
- }
1782
- throw new Error("对象池最大数量超出:" + this._maxCount);
1783
- }
1784
- /**
1785
- * 回收到池中
1786
- * @param value
1787
- * @returns
1788
- */
1789
- recover(value) {
1790
- if (this._cacheStack.indexOf(value) > -1) {
1791
- throw new Error("重复回收!");
1792
- }
1793
- let index = this._usingArray.indexOf(value);
1794
- if (index < 0) {
1795
- throw new Error("对象不属于改对象池!");
1796
- }
1797
- //重置
1798
- value.reset();
1799
- this._usingArray.splice(index, 1);
1800
- this._cacheStack.push(value);
1801
- }
1802
- /**
1803
- * 批量回收
1804
- * @param list
1805
- */
1806
- recoverList(list) {
1807
- for (let index = 0; index < list.length; index++) {
1808
- const element = list[index];
1809
- this.recover(element);
1810
- }
1811
- }
1812
- /**
1813
- * 将所有使用中的对象都回收到池中
1814
- */
1815
- recoverAll() {
1816
- for (let index = 0; index < this._usingArray.length; index++) {
1817
- const element = this._usingArray[index];
1818
- this.recover(element);
1819
- }
1820
- }
1821
- destroy() {
1822
- this.recoverAll();
1823
- for (let index = 0; index < this._cacheStack.length; index++) {
1824
- const element = this._cacheStack[index];
1825
- element.destroy();
1826
- }
1827
- this._cacheStack.length = 0;
1828
- this._cacheStack = null;
1829
- this._usingArray.length = 0;
1830
- this._usingArray = null;
1831
- }
1832
- }
1833
-
1834
- /**
1835
- * <p><code>Handler</code> 是事件处理器类。</p>
1836
- * <p>推荐使用 Handler.create() 方法从对象池创建,减少对象创建消耗。创建的 Handler 对象不再使用后,可以使用 Handler.recover() 将其回收到对象池,回收后不要再使用此对象,否则会导致不可预料的错误。</p>
1837
- * <p><b>注意:</b>由于鼠标事件也用本对象池,不正确的回收及调用,可能会影响鼠标事件的执行。</p>
1838
- */
1839
- class Handler {
2311
+ class ADBehaviorReporter {
2312
+ constructor(baseAble) {
2313
+ this.baseAble = baseAble;
2314
+ this._groupCount = {};
2315
+ }
1840
2316
  /**
1841
- * 根据指定的属性值,创建一个 <code>Handler</code> 类的实例。
1842
- * @param caller 执行域。
1843
- * @param method 处理函数。
1844
- * @param args 函数参数。
1845
- * @param once 是否只执行一次。
2317
+ * 重置单个模块的广告计数
2318
+ * @param group 模块名称,默认为game
1846
2319
  */
1847
- constructor(caller = null, method = null, args = null, once = false) {
1848
- /** 表示是否只执行一次。如果为true,回调后执行recover()进行回收,回收后会被再利用,默认为false 。*/
1849
- this.once = false;
1850
- /**@private */
1851
- this._id = 0;
1852
- this.setTo(caller, method, args, once);
2320
+ resetGroupCount(group = "game") {
2321
+ this._groupCount[group] = 0;
1853
2322
  }
1854
2323
  /**
1855
- * 设置此对象的指定属性值。
1856
- * @param caller 执行域(this)。
1857
- * @param method 回调方法。
1858
- * @param args 携带的参数。
1859
- * @param once 是否只执行一次,如果为true,执行后执行recover()进行回收。
1860
- * @return 返回 handler 本身。
2324
+ * 开始加载广告
2325
+ * @param type 广告类型
2326
+ * @param from 广告来源
2327
+ * @param msg 广告失败原因
1861
2328
  */
1862
- setTo(caller, method, args, once = false) {
1863
- this._id = Handler._gid++;
1864
- this.caller = caller;
1865
- this.method = method;
1866
- this.args = args;
1867
- this.once = once;
1868
- return this;
2329
+ onStartLoad(type, from, msg) {
2330
+ this.report(type, ADEvent.LOAD, from, msg);
1869
2331
  }
1870
2332
  /**
1871
- * 执行处理器。
2333
+ * 广告加载完成
2334
+ * @param type 广告类型
2335
+ * @param from 广告来源
1872
2336
  */
1873
- run() {
1874
- if (this.method == null)
1875
- return null;
1876
- var id = this._id;
1877
- var result = this.method.apply(this.caller, this.args);
1878
- this._id === id && this.once && this.recover();
1879
- return result;
2337
+ onLoadComplete(type, from) {
2338
+ this.report(type, ADEvent.LOAD_COMPLETE, from);
1880
2339
  }
1881
2340
  /**
1882
- * 执行处理器,并携带额外数据。
1883
- * @param data 附加的回调数据,可以是单数据或者Array(作为多参)。
2341
+ * 广告加载失败
2342
+ * @param type 广告类型
2343
+ * @param from 广告来源
2344
+ * @param msg 广告失败原因
1884
2345
  */
1885
- runWith(data) {
1886
- if (this.method == null)
1887
- return null;
1888
- var id = this._id;
1889
- if (data == null)
1890
- var result = this.method.apply(this.caller, this.args);
1891
- else if (!this.args && !data.unshift)
1892
- result = this.method.call(this.caller, data);
1893
- else if (this.args)
1894
- result = this.method.apply(this.caller, this.args.concat(data));
1895
- else
1896
- result = this.method.apply(this.caller, data);
1897
- this._id === id && this.once && this.recover();
1898
- return result;
2346
+ onLoadFail(type, from, msg) {
2347
+ this.report(type, ADEvent.LOAD_FAIL, from, msg);
1899
2348
  }
1900
2349
  /**
1901
- * 清理对象引用。
2350
+ * 显示广告
2351
+ * @param type 广告类型
2352
+ * @param from 广告来源
1902
2353
  */
1903
- clear() {
1904
- this.caller = null;
1905
- this.method = null;
1906
- this.args = null;
1907
- return this;
1908
- }
1909
- reset() {
1910
- this.clear();
2354
+ onShow(type, from) {
2355
+ this.report(type, ADEvent.SHOW, from);
1911
2356
  }
1912
- destroy() {
1913
- this.clear();
2357
+ /**
2358
+ * 广告显示完成
2359
+ * @param type 广告类型
2360
+ * @param from 广告来源
2361
+ */
2362
+ onShowComplete(type, from) {
2363
+ this.report(type, ADEvent.SHOW_COMPLETE, from, undefined, true);
1914
2364
  }
1915
2365
  /**
1916
- * 清理并回收到 Handler 对象池内。
2366
+ * 广告显示失败
2367
+ * @param type 广告类型
2368
+ * @param from 广告来源
2369
+ * @param msg 广告失败原因
1917
2370
  */
1918
- recover() {
1919
- if (this._id > 0) {
1920
- this._id = 0;
1921
- Handler._pool.recover(this);
1922
- }
2371
+ onShowFail(type, from, msg) {
2372
+ this.report(type, ADEvent.SHOW_FAIL, from, msg);
1923
2373
  }
1924
- equal(value) {
1925
- return value === this;
2374
+ /**
2375
+ * 用户关闭广告
2376
+ * @param type 广告类型
2377
+ * @param from 广告来源
2378
+ */
2379
+ onCloseByUser(type, from) {
2380
+ this.report(type, ADEvent.CLOSE_BY_USER, from);
1926
2381
  }
1927
2382
  /**
1928
- * 从对象池内创建一个Handler,默认会执行一次并立即回收,如果不需要自动回收,设置once参数为false。
1929
- * @param caller 执行域(this)。
1930
- * @param method 回调方法。
1931
- * @param args 携带的参数。
1932
- * @param once 是否只执行一次,如果为true,回调后执行recover()进行回收,默认为true。
1933
- * @return 返回创建的handler实例。
2383
+ * 上报广告事件
2384
+ * @param type 广告类型
2385
+ * @param event 广告事件
2386
+ * @param from 广告来源
2387
+ * @param msg 广告失败原因
1934
2388
  */
1935
- static create(caller, method, args = null, once = true) {
1936
- return Handler._pool.allocate().setTo(caller, method, args, once);
2389
+ report(type, event, from, msg, impression = false) {
2390
+ const source = Object.assign({}, (from || {}));
2391
+ const group = source.group || "game";
2392
+ delete source.group;
2393
+ if (!this._groupCount[group]) {
2394
+ this._groupCount[group] = 0;
2395
+ }
2396
+ const data = Object.assign(Object.assign({}, source), { group, adType: type, lifecycle: event, count: event == ADEvent.SHOW_COMPLETE
2397
+ ? ++this._groupCount[group]
2398
+ : this._groupCount[group] });
2399
+ if (msg) {
2400
+ data.message = msg;
2401
+ }
2402
+ this.baseAble.report(impression ? AnalyticsBehavior.AD_IMPRESSION : AnalyticsBehavior.AD_LIFECYCLE, data);
1937
2403
  }
1938
2404
  }
1939
- /**@private handler对象池*/
1940
- Handler._pool = new Pool(Handler);
1941
- /**@private */
1942
- Handler._gid = 1;
1943
2405
 
1944
2406
  /**
1945
2407
  * <code>EventDispatcher</code> 类是可调度事件的所有类的基类。
@@ -2605,13 +3067,13 @@ LevelOnlineConfig = __decorate([
2605
3067
 
2606
3068
  var GameLeaveType;
2607
3069
  (function (GameLeaveType) {
2608
- GameLeaveType["success"] = "lv_success";
2609
- GameLeaveType["fail"] = "lv_fail";
2610
- GameLeaveType["leave"] = "lv_leave";
2611
- GameLeaveType["skip"] = "lv_skip";
2612
- GameLeaveType["revive"] = "lv_revive";
2613
- GameLeaveType["break"] = "lv_break";
2614
- GameLeaveType["retry"] = "lv_retry";
3070
+ GameLeaveType["success"] = "success";
3071
+ GameLeaveType["fail"] = "fail";
3072
+ GameLeaveType["leave"] = "leave";
3073
+ GameLeaveType["skip"] = "skip";
3074
+ GameLeaveType["revive"] = "revive";
3075
+ GameLeaveType["break"] = "break";
3076
+ GameLeaveType["retry"] = "retry";
2615
3077
  })(GameLeaveType || (GameLeaveType = {}));
2616
3078
  /**
2617
3079
  * 关卡行为自动上报器
@@ -2630,7 +3092,7 @@ class LevelBehaviorReporter {
2630
3092
  this.reset();
2631
3093
  this._setTimers();
2632
3094
  App.onHide(this._leaveApp, this);
2633
- this.baseAble.report("lv_enter", context);
3095
+ this.baseAble.report(AnalyticsBehavior.LEVEL_START, context);
2634
3096
  }
2635
3097
  end(type, data) {
2636
3098
  const context = this._getContext();
@@ -2641,7 +3103,7 @@ class LevelBehaviorReporter {
2641
3103
  const levelsession = this._game.getCurrentLevelSession();
2642
3104
  // 有效操作的平均思考时间
2643
3105
  const time = levelsession.stepsUsed > 0 ? Math.floor(levelsession.thinkTimeTotal / levelsession.stepsUsed) : 0;
2644
- this.baseAble.report(type, Object.assign(Object.assign(Object.assign({}, context), data), { time }));
3106
+ this.baseAble.report(AnalyticsBehavior.LEVEL_END, Object.assign(Object.assign(Object.assign({}, context), data), { result: type, averageThinkTimeMs: time }));
2645
3107
  this.reset();
2646
3108
  }
2647
3109
  reportLeave(data) {
@@ -2649,47 +3111,39 @@ class LevelBehaviorReporter {
2649
3111
  if (!context) {
2650
3112
  return;
2651
3113
  }
2652
- this.baseAble.report(GameLeaveType.leave, Object.assign(Object.assign(Object.assign({}, context), { name: "切出游戏" }), data));
3114
+ this.baseAble.report(AnalyticsBehavior.LEVEL_PAUSE, Object.assign(Object.assign(Object.assign({}, context), { reason: "app_hide" }), data));
2653
3115
  }
2654
3116
  reportTimeout(data) {
2655
3117
  const context = this._getContext();
2656
3118
  if (!context) {
2657
3119
  return;
2658
3120
  }
2659
- this.baseAble.report("lv_timeout", Object.assign(Object.assign(Object.assign({}, context), { name: "超时" }), data));
3121
+ this.baseAble.report(AnalyticsBehavior.LEVEL_TIMEOUT, Object.assign(Object.assign(Object.assign({}, context), { reason: "timeout" }), data));
2660
3122
  }
2661
3123
  reportItem(name, data) {
2662
3124
  const context = this._getContext();
2663
3125
  if (!context) {
2664
3126
  return;
2665
3127
  }
2666
- this.baseAble.report("lv_item", Object.assign(Object.assign(Object.assign({}, context), { name: name.toLocaleLowerCase() }), data));
3128
+ this.baseAble.report(AnalyticsBehavior.LEVEL_ITEM_USE, Object.assign(Object.assign(Object.assign({}, context), { itemName: name.toLocaleLowerCase() }), data));
2667
3129
  }
2668
3130
  reset() {
2669
- this.baseAble.cancelTime(GameLeaveType.success);
2670
- this.baseAble.cancelTime(GameLeaveType.leave);
2671
- this.baseAble.cancelTime(GameLeaveType.fail);
2672
- this.baseAble.cancelTime(GameLeaveType.skip);
2673
- this.baseAble.cancelTime(GameLeaveType.revive);
2674
- this.baseAble.cancelTime(GameLeaveType.break);
2675
- this.baseAble.cancelTime(GameLeaveType.retry);
2676
- this.baseAble.cancelTime("lv_timeout");
2677
- this.baseAble.cancelTime("ad");
3131
+ this.baseAble.cancelTime(AnalyticsBehavior.LEVEL_END);
3132
+ this.baseAble.cancelTime(AnalyticsBehavior.LEVEL_PAUSE);
3133
+ this.baseAble.cancelTime(AnalyticsBehavior.LEVEL_TIMEOUT);
3134
+ this.baseAble.cancelTime(AnalyticsBehavior.AD_LIFECYCLE);
3135
+ this.baseAble.cancelTime(AnalyticsBehavior.AD_IMPRESSION);
2678
3136
  App.offHide(this._leaveApp, this);
2679
3137
  }
2680
3138
  _leaveApp() {
2681
3139
  this.reportLeave();
2682
3140
  }
2683
3141
  _setTimers() {
2684
- this.baseAble.time(GameLeaveType.success, false);
2685
- this.baseAble.time(GameLeaveType.leave, false);
2686
- this.baseAble.time(GameLeaveType.fail, false);
2687
- this.baseAble.time(GameLeaveType.skip, false);
2688
- this.baseAble.time(GameLeaveType.revive, false);
2689
- this.baseAble.time(GameLeaveType.break, false);
2690
- this.baseAble.time(GameLeaveType.retry, false);
2691
- this.baseAble.time("lv_timeout", false);
2692
- this.baseAble.time("ad", false);
3142
+ this.baseAble.time(AnalyticsBehavior.LEVEL_END, false);
3143
+ this.baseAble.time(AnalyticsBehavior.LEVEL_PAUSE, false);
3144
+ this.baseAble.time(AnalyticsBehavior.LEVEL_TIMEOUT, false);
3145
+ this.baseAble.time(AnalyticsBehavior.AD_LIFECYCLE, false);
3146
+ this.baseAble.time(AnalyticsBehavior.AD_IMPRESSION, false);
2693
3147
  }
2694
3148
  _getContext() {
2695
3149
  return this._game.getCurrentBehaviorContext();
@@ -3473,7 +3927,7 @@ class GameDimension extends BaseDimension {
3473
3927
  if (!this._currentLevelSession) {
3474
3928
  return null;
3475
3929
  }
3476
- return Object.assign({ id: this._currentLevelSession.levelId.toString(), index: this._currentLevelSession.levelIndex, type: this._gameFlag, progress: this._currentLevelSession.progress, code: Number((_b = (_a = this._currentEnterParams) === null || _a === void 0 ? void 0 : _a.repeat) !== null && _b !== void 0 ? _b : 0) }, this._currentEnterParams);
3930
+ return Object.assign(Object.assign({}, this._currentEnterParams), { levelId: this._currentLevelSession.levelId.toString(), levelIndex: this._currentLevelSession.levelIndex, gameId: this._gameFlag, progress: this._currentLevelSession.progress, repeatCount: Number((_b = (_a = this._currentEnterParams) === null || _a === void 0 ? void 0 : _a.repeat) !== null && _b !== void 0 ? _b : 0) });
3477
3931
  }
3478
3932
  onLevelStart(id, index, data) {
3479
3933
  this._currentEnterParams = data;
@@ -3772,7 +4226,7 @@ class LaunchAnalyticsAble {
3772
4226
  * 标记应用准备就绪,开始统计启动时间
3773
4227
  */
3774
4228
  ready() {
3775
- this._baseAble.time("app_launch");
4229
+ this._baseAble.time(AnalyticsBehavior.APP_LAUNCH);
3776
4230
  }
3777
4231
  /**
3778
4232
  * 上报启动事件
@@ -3781,7 +4235,7 @@ class LaunchAnalyticsAble {
3781
4235
  */
3782
4236
  report(name, data) {
3783
4237
  const payload = Object.assign(Object.assign({}, (data || {})), { name });
3784
- this._baseAble.report("app_launch", payload);
4238
+ this._baseAble.report(AnalyticsBehavior.APP_LAUNCH, payload);
3785
4239
  }
3786
4240
  }
3787
4241
 
@@ -3999,7 +4453,9 @@ class SessionAnalyticsAble {
3999
4453
  this._dimension = new SessionDimension();
4000
4454
  }
4001
4455
  recordLogin() {
4002
- this._baseAble.report("login", { msg: JSON.stringify(publisher.publisher.enterOptions.getAllOption()) });
4456
+ this._baseAble.report(AnalyticsBehavior.SESSION_LOGIN, {
4457
+ options: JSON.stringify(publisher.publisher.enterOptions.getAllOption()),
4458
+ });
4003
4459
  this._dimension.recordLogin();
4004
4460
  }
4005
4461
  updateSessionDuration() {
@@ -4081,9 +4537,15 @@ class SocialAnalyticsAble {
4081
4537
  this._baseAble = baseAble;
4082
4538
  this._socialDimension = new SocialDimension();
4083
4539
  }
4540
+ share(data) {
4541
+ this._baseAble.report(AnalyticsBehavior.SOCIAL_SHARE, data);
4542
+ data.phase === "success" && this._socialDimension.recordShare();
4543
+ }
4544
+ /**
4545
+ * @deprecated 请改用 share,并明确传入分享阶段。
4546
+ */
4084
4547
  recordShare(data) {
4085
- this._baseAble.report("share", data);
4086
- this._socialDimension.recordShare();
4548
+ this.share(Object.assign(Object.assign({}, data), { phase: "success" }));
4087
4549
  }
4088
4550
  recordInvite(success = false) {
4089
4551
  this._socialDimension.recordInvite(success);
@@ -4095,16 +4557,104 @@ class SocialAnalyticsAble {
4095
4557
  this._socialDimension.recordInteraction();
4096
4558
  }
4097
4559
  recordSubscribeShow(name) {
4098
- this._baseAble.report("subscribe_show", { name });
4560
+ this._baseAble.report(AnalyticsBehavior.SOCIAL_SUBSCRIBE_SHOW, { name });
4099
4561
  }
4100
4562
  recordSubscribe(name, code) {
4101
- this._baseAble.report("subscribe", { name, code });
4563
+ this._baseAble.report(AnalyticsBehavior.SOCIAL_SUBSCRIBE, { name, code });
4102
4564
  }
4103
4565
  getMetrics() {
4104
4566
  return this._socialDimension.getMetrics();
4105
4567
  }
4106
4568
  }
4107
4569
 
4570
+ /**
4571
+ * 新手引导统计能力。只提供稳定的业务动作,不维护引导流程状态。
4572
+ */
4573
+ class TutorialAnalyticsAble {
4574
+ constructor(_baseAble) {
4575
+ this._baseAble = _baseAble;
4576
+ }
4577
+ begin(data) {
4578
+ this._baseAble.report(AnalyticsBehavior.TUTORIAL_BEGIN, data);
4579
+ }
4580
+ complete(data) {
4581
+ this._baseAble.report(AnalyticsBehavior.TUTORIAL_COMPLETE, data);
4582
+ }
4583
+ skip(data) {
4584
+ this._baseAble.report(AnalyticsBehavior.TUTORIAL_SKIP, data);
4585
+ }
4586
+ }
4587
+
4588
+ /**
4589
+ * 支付漏斗统计能力。价格由业务提供,value 由框架按商品明细统一计算。
4590
+ */
4591
+ class PayAnalyticsAble {
4592
+ constructor(_baseAble) {
4593
+ this._baseAble = _baseAble;
4594
+ }
4595
+ begin(data) {
4596
+ this.report(AnalyticsBehavior.PAY_BEGIN, data);
4597
+ }
4598
+ purchase(data) {
4599
+ this.report(AnalyticsBehavior.PAY_PURCHASE, data);
4600
+ }
4601
+ pending(data) {
4602
+ this.report(AnalyticsBehavior.PAY_PENDING, data);
4603
+ }
4604
+ cancel(data) {
4605
+ this.report(AnalyticsBehavior.PAY_CANCEL, data);
4606
+ }
4607
+ fail(data) {
4608
+ this.report(AnalyticsBehavior.PAY_FAIL, data);
4609
+ }
4610
+ report(eventName, data) {
4611
+ const normalized = this.normalize(data);
4612
+ if (!normalized) {
4613
+ return;
4614
+ }
4615
+ this._baseAble.report(eventName, normalized);
4616
+ }
4617
+ normalize(data) {
4618
+ const transactionId = String(data && data.transactionId || "").trim();
4619
+ const currency = String(data && data.currency || "").trim().toUpperCase();
4620
+ const items = data && data.items;
4621
+ if (!transactionId) {
4622
+ return this.invalid("transactionId 不能为空");
4623
+ }
4624
+ if (!/^[A-Z]{3}$/.test(currency)) {
4625
+ return this.invalid(`currency 必须是三位大写货币代码: ${currency}`);
4626
+ }
4627
+ if (!Array.isArray(items) || items.length === 0) {
4628
+ return this.invalid("items 不能为空");
4629
+ }
4630
+ const normalizedItems = [];
4631
+ let value = 0;
4632
+ for (let i = 0; i < items.length; i++) {
4633
+ const item = items[i];
4634
+ const itemId = String(item && item.itemId || "").trim();
4635
+ const price = Number(item && item.price);
4636
+ const quantity = item && item.quantity === undefined
4637
+ ? 1
4638
+ : Number(item.quantity);
4639
+ if (!itemId || !Number.isFinite(price) || price < 0) {
4640
+ return this.invalid(`items[${i}] 的 itemId/price 无效`);
4641
+ }
4642
+ if (!Number.isInteger(quantity) || quantity <= 0) {
4643
+ return this.invalid(`items[${i}] 的 quantity 必须是正整数`);
4644
+ }
4645
+ const normalizedItem = Object.assign(Object.assign({}, item), { itemId, price, quantity });
4646
+ normalizedItems.push(normalizedItem);
4647
+ value += price * quantity;
4648
+ }
4649
+ return Object.assign(Object.assign({}, data), { transactionId,
4650
+ currency, items: normalizedItems, value: Math.round(value * 1000000) / 1000000 });
4651
+ }
4652
+ invalid(message) {
4653
+ console.warn(`[Analytics.pay] ${message},本次事件已忽略。`);
4654
+ return null;
4655
+ }
4656
+ }
4657
+
4108
4658
  /**
4109
4659
  * 请求进度改变时调度。
4110
4660
  * @eventType Event.PROGRESS
@@ -5877,10 +6427,13 @@ class KeytopsAnalyticsSender extends EmptyAnalyticsSender {
5877
6427
  }
5878
6428
  });
5879
6429
  }
5880
- send(eventName, data) {
6430
+ mapEvent(eventName, eventData) {
6431
+ return mapCanonicalEventToLegacy(eventName, eventData);
6432
+ }
6433
+ send(eventName, eventData, userProperties) {
5881
6434
  return __awaiter(this, void 0, void 0, function* () {
5882
- const payload = data && typeof data === "object" && !Array.isArray(data)
5883
- ? Object.assign({}, data) : { value: data };
6435
+ const payload = eventData && typeof eventData === "object" && !Array.isArray(eventData)
6436
+ ? Object.assign(Object.assign({}, userProperties), eventData) : Object.assign({}, userProperties);
5884
6437
  let msg_data = {
5885
6438
  appid: publisher.appId,
5886
6439
  openid: String(storage.userId || publisher.login.openID || ""),
@@ -5897,7 +6450,277 @@ class KeytopsAnalyticsSender extends EmptyAnalyticsSender {
5897
6450
  if (this._eventCache.length >= countLimit || this._currentBufferedBytes() >= byteLimit) {
5898
6451
  this._scheduleFlush(0);
5899
6452
  }
5900
- });
6453
+ });
6454
+ }
6455
+ }
6456
+
6457
+ /*
6458
+ @name: NativeHelper
6459
+ @desc: 原生函数调用代理
6460
+ @author: timoo
6461
+ @date: 2022/11/26
6462
+ */
6463
+ class NativeHelper {
6464
+ static call(className, methodName, ...args) {
6465
+ NativeHelper.impl.call(className, methodName, ...args);
6466
+ }
6467
+ static callWithReturnType(className, methodName, returnType, ...args) {
6468
+ return NativeHelper.impl.callWithReturnType(className, methodName, returnType, ...args);
6469
+ }
6470
+ static registerCallback(caller, method, times, ...args) {
6471
+ return NativeHelper.impl.registerCallback(caller, method, times, ...args);
6472
+ }
6473
+ static registerCallbackOnce(caller, method, ...args) {
6474
+ return NativeHelper.impl.registerCallback(caller, method, 1, ...args);
6475
+ }
6476
+ static get impl() {
6477
+ if (this._impl == null) {
6478
+ this._impl = Injector.getInject(NativeHelper.KEY);
6479
+ }
6480
+ if (this._impl == null) {
6481
+ throw new Error(NativeHelper.KEY + " 未注入!");
6482
+ }
6483
+ return this._impl;
6484
+ }
6485
+ }
6486
+ NativeHelper.KEY = "NativeHelper";
6487
+
6488
+ const DEFAULT_IGNORED_PARAMETERS = [
6489
+ "device_system",
6490
+ "device_platform",
6491
+ "device_brand",
6492
+ "device_model",
6493
+ "app_version",
6494
+ ];
6495
+ const RESERVED_PREFIXES = ["firebase_", "google_", "ga_"];
6496
+ const RESERVED_USER_PROPERTIES = new Set([
6497
+ "first_open_time",
6498
+ "first_visit_time",
6499
+ "last_deep_link_referrer",
6500
+ "user_id",
6501
+ "first_open_after_install",
6502
+ ]);
6503
+ const FIREBASE_EVENT_NAMES = {
6504
+ [AnalyticsBehavior.SESSION_LOGIN]: "login",
6505
+ [AnalyticsBehavior.LEVEL_START]: "level_start",
6506
+ [AnalyticsBehavior.LEVEL_END]: "level_end",
6507
+ [AnalyticsBehavior.AD_IMPRESSION]: "ad_impression",
6508
+ [AnalyticsBehavior.TUTORIAL_BEGIN]: "tutorial_begin",
6509
+ [AnalyticsBehavior.TUTORIAL_COMPLETE]: "tutorial_complete",
6510
+ [AnalyticsBehavior.TUTORIAL_SKIP]: "tutorial_skip",
6511
+ [AnalyticsBehavior.PAY_BEGIN]: "begin_checkout",
6512
+ [AnalyticsBehavior.PAY_PURCHASE]: "purchase",
6513
+ [AnalyticsBehavior.PAY_PENDING]: "purchase_pending",
6514
+ [AnalyticsBehavior.PAY_CANCEL]: "purchase_cancel",
6515
+ [AnalyticsBehavior.PAY_FAIL]: "purchase_fail",
6516
+ };
6517
+ /**
6518
+ * Firebase Android Analytics 上报器。
6519
+ *
6520
+ * TS 端属于框架,Java Bridge 仍由具体游戏工程提供。非原生环境会安全忽略调用。
6521
+ */
6522
+ class FirebaseAnalyticsSender extends EmptyAnalyticsSender {
6523
+ constructor(config, exclude) {
6524
+ super(exclude);
6525
+ this._lastUserProperties = {};
6526
+ if (!config || !String(config.bridgeClassName || "").trim()) {
6527
+ throw new Error("FirebaseAnalyticsSender.bridgeClassName 不能为空");
6528
+ }
6529
+ this._config = {
6530
+ bridgeClassName: String(config.bridgeClassName).trim(),
6531
+ collectionEnabled: config.collectionEnabled !== false,
6532
+ ignoredParameters: config.ignoredParameters || DEFAULT_IGNORED_PARAMETERS,
6533
+ maxParameters: Math.min(Math.max(config.maxParameters || 25, 1), 25),
6534
+ supportsStructuredItems: !!config.supportsStructuredItems,
6535
+ debug: !!config.debug,
6536
+ };
6537
+ this._ignoredParameters = new Set(this._config.ignoredParameters);
6538
+ if (this.canSend) {
6539
+ NativeHelper.call(this._config.bridgeClassName, "setCollectionEnabled", this._config.collectionEnabled);
6540
+ }
6541
+ }
6542
+ get canSend() {
6543
+ var _a;
6544
+ const target = globalThis;
6545
+ const sys = target.cc && target.cc.sys;
6546
+ if (sys) {
6547
+ return !!(sys.isNative &&
6548
+ sys.os === ((_a = sys.OS) === null || _a === void 0 ? void 0 : _a.ANDROID) &&
6549
+ (target.jsb || target.native));
6550
+ }
6551
+ return !!(target.jsb || target.native);
6552
+ }
6553
+ setUserId(userId) {
6554
+ const normalized = userId == null ? null : String(userId).trim();
6555
+ const nextUserId = normalized ? this.truncate(normalized, 256) : null;
6556
+ if (this._lastUserId === nextUserId) {
6557
+ return;
6558
+ }
6559
+ this._lastUserId = nextUserId;
6560
+ if (!this.canSend) {
6561
+ return;
6562
+ }
6563
+ NativeHelper.call(this._config.bridgeClassName, nextUserId ? "setUserId" : "clearUserId", ...(nextUserId ? [nextUserId] : []));
6564
+ }
6565
+ mapEvent(eventName, eventData) {
6566
+ const data = this.mapParameters(eventName, eventData);
6567
+ let mappedName = FIREBASE_EVENT_NAMES[eventName] || eventName.replace(/\./g, "_");
6568
+ if (eventName === AnalyticsBehavior.SOCIAL_SHARE) {
6569
+ const phase = String(data.phase || "");
6570
+ mappedName = phase === "success" ? "share" : `share_${phase || "unknown"}`;
6571
+ }
6572
+ else if (eventName === AnalyticsBehavior.AD_LIFECYCLE) {
6573
+ mappedName = "ad_lifecycle";
6574
+ }
6575
+ return { eventName: mappedName, data };
6576
+ }
6577
+ send(eventName, eventData, userProperties) {
6578
+ return __awaiter(this, void 0, void 0, function* () {
6579
+ if (!this.canSend || !this._config.collectionEnabled) {
6580
+ return;
6581
+ }
6582
+ if (!this.isValidName(eventName, 40)) {
6583
+ this.warn(`忽略无效 Firebase 事件名: ${eventName}`);
6584
+ return;
6585
+ }
6586
+ if ((eventName === "purchase" || eventName === "begin_checkout") &&
6587
+ Array.isArray(eventData.items) &&
6588
+ !this._config.supportsStructuredItems) {
6589
+ this.syncUserProperties(userProperties);
6590
+ this.warn("当前 Java Bridge 不支持 Bundle[] items,支付事件已忽略。");
6591
+ return;
6592
+ }
6593
+ this.syncUserProperties(userProperties);
6594
+ const parameters = this.normalizeParameters(eventData);
6595
+ NativeHelper.call(this._config.bridgeClassName, "logEvent", eventName, JSON.stringify(parameters));
6596
+ });
6597
+ }
6598
+ mapParameters(eventName, eventData) {
6599
+ const data = Object.assign({}, eventData);
6600
+ if (eventName === AnalyticsBehavior.LEVEL_START ||
6601
+ eventName === AnalyticsBehavior.LEVEL_END) {
6602
+ if (data.levelId !== undefined) {
6603
+ data.level_name = data.levelId;
6604
+ delete data.levelId;
6605
+ }
6606
+ }
6607
+ if (eventName === AnalyticsBehavior.SOCIAL_SHARE) {
6608
+ if (data.contentType !== undefined) {
6609
+ data.content_type = data.contentType;
6610
+ delete data.contentType;
6611
+ }
6612
+ if (data.itemId !== undefined) {
6613
+ data.item_id = data.itemId;
6614
+ delete data.itemId;
6615
+ }
6616
+ }
6617
+ if (eventName === AnalyticsBehavior.PAY_BEGIN ||
6618
+ eventName === AnalyticsBehavior.PAY_PURCHASE) {
6619
+ if (data.transactionId !== undefined) {
6620
+ data.transaction_id = data.transactionId;
6621
+ delete data.transactionId;
6622
+ }
6623
+ if (Array.isArray(data.items)) {
6624
+ data.items = data.items.map((item) => {
6625
+ if (item.itemId === undefined) {
6626
+ return Object.assign({}, item);
6627
+ }
6628
+ const mapped = Object.assign(Object.assign({}, item), { item_id: item.itemId });
6629
+ delete mapped.itemId;
6630
+ if (item.itemName !== undefined) {
6631
+ mapped.item_name = item.itemName;
6632
+ delete mapped.itemName;
6633
+ }
6634
+ if (item.itemCategory !== undefined) {
6635
+ mapped.item_category = item.itemCategory;
6636
+ delete mapped.itemCategory;
6637
+ }
6638
+ return mapped;
6639
+ });
6640
+ }
6641
+ }
6642
+ return data;
6643
+ }
6644
+ syncUserProperties(properties) {
6645
+ const previous = this._lastUserProperties;
6646
+ Object.keys(previous).forEach((key) => {
6647
+ if (!Object.prototype.hasOwnProperty.call(properties, key)) {
6648
+ this.setUserProperty(key, null);
6649
+ }
6650
+ });
6651
+ Object.keys(properties).forEach((key) => {
6652
+ if (previous[key] !== properties[key]) {
6653
+ this.setUserProperty(key, properties[key]);
6654
+ }
6655
+ });
6656
+ this._lastUserProperties = Object.assign({}, properties);
6657
+ }
6658
+ setUserProperty(key, value) {
6659
+ if (!this.isValidName(key, 24) || RESERVED_USER_PROPERTIES.has(key)) {
6660
+ this.warn(`忽略无效 Firebase 用户属性: ${key}`);
6661
+ return;
6662
+ }
6663
+ if (value == null) {
6664
+ NativeHelper.call(this._config.bridgeClassName, "clearUserProperty", key);
6665
+ return;
6666
+ }
6667
+ const normalized = typeof value === "boolean"
6668
+ ? (value ? "1" : "0")
6669
+ : String(value);
6670
+ NativeHelper.call(this._config.bridgeClassName, "setUserProperty", key, this.truncate(normalized, 36));
6671
+ }
6672
+ normalizeParameters(data) {
6673
+ const result = {};
6674
+ const keys = Object.keys(data || {});
6675
+ for (let i = 0; i < keys.length; i++) {
6676
+ if (Object.keys(result).length >= this._config.maxParameters) {
6677
+ this.warn(`Firebase 事件参数超过 ${this._config.maxParameters} 个,后续参数已忽略。`);
6678
+ break;
6679
+ }
6680
+ const key = keys[i];
6681
+ if (this._ignoredParameters.has(key) || !this.isValidName(key, 40)) {
6682
+ continue;
6683
+ }
6684
+ const value = data[key];
6685
+ if (key === "items" && Array.isArray(value)) {
6686
+ if (this._config.supportsStructuredItems) {
6687
+ result[key] = value.map((item) => (Object.assign({}, item)));
6688
+ }
6689
+ continue;
6690
+ }
6691
+ const normalized = this.normalizeValue(value);
6692
+ if (normalized !== undefined) {
6693
+ result[key] = normalized;
6694
+ }
6695
+ }
6696
+ return result;
6697
+ }
6698
+ normalizeValue(value) {
6699
+ if (value == null) {
6700
+ return undefined;
6701
+ }
6702
+ if (typeof value === "boolean") {
6703
+ return value ? 1 : 0;
6704
+ }
6705
+ if (typeof value === "number") {
6706
+ return Number.isFinite(value) ? value : undefined;
6707
+ }
6708
+ if (typeof value === "string") {
6709
+ return this.truncate(value, 100);
6710
+ }
6711
+ return undefined;
6712
+ }
6713
+ isValidName(name, maxLength) {
6714
+ if (!name || name.length > maxLength || !/^[A-Za-z][A-Za-z0-9_]*$/.test(name)) {
6715
+ return false;
6716
+ }
6717
+ return !RESERVED_PREFIXES.some((prefix) => name.startsWith(prefix));
6718
+ }
6719
+ truncate(value, maxLength) {
6720
+ return value.length > maxLength ? value.slice(0, maxLength) : value;
6721
+ }
6722
+ warn(message) {
6723
+ this._config.debug && console.warn(`[FirebaseAnalyticsSender] ${message}`);
5901
6724
  }
5902
6725
  }
5903
6726
 
@@ -5909,6 +6732,8 @@ class AnalyticsManager {
5909
6732
  this._session = null;
5910
6733
  this._launch = null;
5911
6734
  this._social = null;
6735
+ this._tutorial = null;
6736
+ this._pay = null;
5912
6737
  this._assignmentSender = null;
5913
6738
  }
5914
6739
  hasRelayUrl(config) {
@@ -5961,389 +6786,138 @@ class AnalyticsManager {
5961
6786
  return this._ad;
5962
6787
  }
5963
6788
  /**
5964
- * 会话统计能力,用于会话分析
5965
- */
5966
- get session() {
5967
- if (!this.base.inited) {
5968
- throw new Error("请先通过enable初始化基础统计能力");
5969
- }
5970
- if (!this._session) {
5971
- this._session = new SessionAnalyticsAble(this.base);
5972
- }
5973
- return this._session;
5974
- }
5975
- /**
5976
- * 启动统计能力,用于启动性能分析
5977
- */
5978
- get launch() {
5979
- if (!this.base.inited) {
5980
- throw new Error("请先通过enable初始化基础统计能力");
5981
- }
5982
- if (!this._launch) {
5983
- this._launch = new LaunchAnalyticsAble(this.base);
5984
- }
5985
- return this._launch;
5986
- }
5987
- /**
5988
- * 社交统计能力
5989
- */
5990
- get social() {
5991
- if (!this.base.inited) {
5992
- throw new Error("请先通过enable初始化基础统计能力");
5993
- }
5994
- if (!this._social) {
5995
- this._social = new SocialAnalyticsAble(this.base);
5996
- }
5997
- return this._social;
5998
- }
5999
- /**
6000
- * 启用统计(基础统计能力)
6001
- * @param debugMode 调试模式,是否打印日志信息,默认为false
6002
- * @param senders 上报器列表,允许多个 默认为ALiAnalyticsSender
6003
- * @returns
6004
- */
6005
- enable(debugMode = false, senders) {
6006
- if (this.base.inited) {
6007
- return;
6008
- }
6009
- senders = senders || this.createBehaviorSenders();
6010
- this.base.init(senders, debugMode);
6011
- this.launch.report("enabled");
6012
- }
6013
- get version() {
6014
- return "v1";
6015
- }
6016
- /**
6017
- * 获取所有维度的数据
6018
- * @returns 所有维度的数据
6019
- */
6020
- getMetrics() {
6021
- const result = {};
6022
- result[DimensionType[DimensionType.ACTIVITY]] = this.session.getMetrics();
6023
- result[DimensionType[DimensionType.AD]] = this.ad.getMetrics();
6024
- result[DimensionType[DimensionType.SOCIAL]] = this.social.getMetrics();
6025
- return result;
6026
- }
6027
- get assignmentSender() {
6028
- if (!this._assignmentSender) {
6029
- const analyticsConfig = remoteConfigService.config(SystemOnlineConfig).getAssignmentConfig();
6030
- this._assignmentSender = this.hasRelayUrl(analyticsConfig)
6031
- ? new KeytopsAnalyticsSender(analyticsConfig, analyticsConfig.exclude || ["view"])
6032
- : new EmptyAnalyticsSender();
6033
- }
6034
- return this._assignmentSender;
6035
- }
6036
- reportAssignments(resolveMeta, levelid) {
6037
- if (!resolveMeta) {
6038
- return;
6039
- }
6040
- const method = resolveMeta.method;
6041
- if (!method) {
6042
- throw new Error("method is required");
6043
- }
6044
- const eventName = `${method}_assignment`;
6045
- (resolveMeta.matchedUnits || []).forEach((unit) => {
6046
- const payload = {
6047
- method: method,
6048
- resolve_key: resolveMeta.resolveKey,
6049
- config_name: unit.configName,
6050
- fingerprint: unit.fingerprint,
6051
- };
6052
- if (unit.publishId) {
6053
- payload.publish_id = unit.publishId;
6054
- }
6055
- if (unit.variantId) {
6056
- payload.variant_id = unit.variantId;
6057
- }
6058
- if (unit.variantFingerprint) {
6059
- payload.variant_fingerprint = unit.variantFingerprint;
6060
- }
6061
- if (levelid !== undefined) {
6062
- payload.level_id = levelid;
6063
- }
6064
- this.assignmentSender.send(eventName, payload);
6065
- });
6066
- }
6067
- }
6068
- /**
6069
- * 埋点统计能力
6070
- */
6071
- const analytics = new AnalyticsManager();
6072
-
6073
- /**
6074
- * 通用计时器实现。
6075
- * 使用 setInterval 驱动 Timer 的内部更新循环。
6076
- */
6077
- class TimerImpl {
6078
- constructor() {
6079
- this._intervalMap = new WeakMap();
6080
- }
6081
- enable(timer) {
6082
- if (this._intervalMap.has(timer)) {
6083
- return;
6084
- }
6085
- const intervalId = setInterval(() => {
6086
- timer["_update"]();
6087
- }, 100);
6088
- this._intervalMap.set(timer, intervalId);
6089
- }
6090
- }
6091
-
6092
- class MathUtils {
6093
- /**
6094
- * 随机
6095
- * @param min
6096
- * @param max
6097
- */
6098
- static random(min, max) {
6099
- this.seed = (this.seed * 9301 + 49297) % 233280;
6100
- let c = this.seed / (233280.0);
6101
- return min + c * (max - min);
6102
- }
6103
- /**
6104
- * 随机整数值
6105
- * @param min
6106
- * @param max
6107
- */
6108
- static randomInt(min, max) {
6109
- return Math.floor(this.random(min, max + 0.999));
6110
- }
6111
- /**
6112
- * 随机唯一稳定值
6113
- * @param min
6114
- * @param max
6115
- * @param clear 是否清除唯一记录
6116
- */
6117
- static randomOnlyInt(min, max, clear) {
6118
- if (clear) {
6119
- this.onlyMap.clear();
6120
- }
6121
- let value = this.randomInt(min, max);
6122
- let tryCount = (max - min) * 2;
6123
- let tryIndex = 0;
6124
- while (this.onlyMap.has(value)) {
6125
- value = this.randomInt(min, max);
6126
- if (tryIndex > tryCount) {
6127
- console.error("所有唯一值已取完");
6128
- return 0;
6129
- }
6130
- tryIndex++;
6131
- }
6132
- this.onlyMap.set(value, true);
6133
- return value;
6134
- }
6135
- /**
6136
- * 获取两点间的角度
6137
- * @param p1 点1
6138
- * @param p2 点2
6139
- */
6140
- static getAngle(p1, p2) {
6141
- return Math.atan((p2.y - p1.y) / (p2.x - p1.x));
6142
- }
6143
- /**
6144
- * 获取两点间的距离
6145
- * @param p1 点1
6146
- * @param p2 点2
6147
- */
6148
- static getDistance(p1, p2) {
6149
- return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
6150
- }
6151
- /**
6152
- * 将角度转为弧度
6153
- * @param angle 角度
6154
- */
6155
- static angleToRadian(angle) {
6156
- return angle * Math.PI / 180;
6157
- }
6158
- /**
6159
- * 求旋转后的点坐标
6160
- * @param angle 角度
6161
- * @param point 旋转前的坐标点
6162
- * @param result
6163
- */
6164
- static getRotationPoint(angle, pointOrDir, result) {
6165
- if (result == null) {
6166
- result = { x: 0, y: 0 };
6167
- }
6168
- //角度转弧度
6169
- angle = angle * (Math.PI / 180);
6170
- result.x = Math.cos(angle) * pointOrDir.x - Math.sin(angle) * pointOrDir.y;
6171
- result.y = Math.cos(angle) * pointOrDir.y + Math.sin(angle) * pointOrDir.x;
6172
- return result;
6173
- }
6174
- }
6175
- /**
6176
- * 随机种子
6177
- */
6178
- MathUtils.seed = 10;
6179
- /**
6180
- * 唯一记录
6181
- */
6182
- MathUtils.onlyMap = new Map();
6183
-
6184
- class StringUtils {
6185
- static random(length, chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") {
6186
- var result = '';
6187
- for (var i = length; i > 0; --i) {
6188
- result += chars[Math.floor(Math.random() * chars.length)];
6189
- }
6190
- return result;
6191
- }
6192
- /**
6193
- * 判断是否是远程资源
6194
- * @param url
6195
- * @returns
6789
+ * 会话统计能力,用于会话分析
6196
6790
  */
6197
- static isRemote(url) {
6198
- if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0) {
6199
- return true;
6791
+ get session() {
6792
+ if (!this.base.inited) {
6793
+ throw new Error("请先通过enable初始化基础统计能力");
6200
6794
  }
6201
- return false;
6795
+ if (!this._session) {
6796
+ this._session = new SessionAnalyticsAble(this.base);
6797
+ }
6798
+ return this._session;
6202
6799
  }
6203
6800
  /**
6204
- * 是否为空
6205
- * @param str
6801
+ * 启动统计能力,用于启动性能分析
6206
6802
  */
6207
- static isEmpty(str) {
6208
- if (str == null || str == undefined || str.length == 0) {
6209
- return true;
6803
+ get launch() {
6804
+ if (!this.base.inited) {
6805
+ throw new Error("请先通过enable初始化基础统计能力");
6210
6806
  }
6211
- return false;
6212
- }
6213
- /**
6214
- * 替换全部字符串
6215
- * @param string src 源串
6216
- * @param string from_ch 被替换的字符
6217
- * @param string to_ch 替换的字符
6218
- *
6219
- * @return string 结果字符串
6220
- */
6221
- static replaceAll(src, from_ch, to_ch) {
6222
- let regExp = new RegExp(from_ch, "g");
6223
- return src.replace(regExp, to_ch);
6807
+ if (!this._launch) {
6808
+ this._launch = new LaunchAnalyticsAble(this.base);
6809
+ }
6810
+ return this._launch;
6224
6811
  }
6225
6812
  /**
6226
- * 参数替换
6227
- * @param str
6228
- * @param rest
6229
- *
6230
- * @example
6231
- *
6232
- * var str:string = "here is some info '{0}' and {1}";
6233
- * trace(StringUtil.substitute(str, 15.4, true));
6234
- *
6235
- * // this will output the following string:
6236
- * // "here is some info '15.4' and true"
6813
+ * 社交统计能力
6237
6814
  */
6238
- static format(str, ...rest) {
6239
- if (str == null)
6240
- return '';
6241
- // Replace all of the parameters in the msg string.
6242
- var len = rest.length;
6243
- var args;
6244
- if (len == 1 && rest[0] instanceof Array) {
6245
- args = rest[0];
6246
- len = args.length;
6247
- }
6248
- else {
6249
- args = rest;
6815
+ get social() {
6816
+ if (!this.base.inited) {
6817
+ throw new Error("请先通过enable初始化基础统计能力");
6250
6818
  }
6251
- for (var i = 0; i < len; i++) {
6252
- str = str.replace(new RegExp("\\{" + i + "\\}", "g"), args[i]);
6819
+ if (!this._social) {
6820
+ this._social = new SocialAnalyticsAble(this.base);
6253
6821
  }
6254
- return str;
6822
+ return this._social;
6255
6823
  }
6256
6824
  /**
6257
- *
6258
- * 格式化数字
6259
- * @param amount 目标数字
6260
- * @param format 支持{1:"", 100:"百", 1000:"千", 10000:"万", 100000:"十万", 1000000:"百万", 10000000:"千万", 100000000:"亿", 1000000000000:"兆"}等
6261
- * @returns
6825
+ * 新手引导统计能力
6262
6826
  */
6263
- static formatNumber(amount, format) {
6264
- if (!format || amount == 0) {
6265
- return `${amount}`;
6827
+ get tutorial() {
6828
+ if (!this.base.inited) {
6829
+ throw new Error("请先通过enable初始化基础统计能力");
6266
6830
  }
6267
- let formatKey = [];
6268
- for (const key in format) {
6269
- if (format.hasOwnProperty(key)) {
6270
- formatKey.push(Number(key));
6271
- }
6831
+ if (!this._tutorial) {
6832
+ this._tutorial = new TutorialAnalyticsAble(this.base);
6272
6833
  }
6273
- if (!formatKey || formatKey.length == 0) {
6274
- return `${amount}`;
6834
+ return this._tutorial;
6835
+ }
6836
+ /**
6837
+ * 支付漏斗统计能力
6838
+ */
6839
+ get pay() {
6840
+ if (!this.base.inited) {
6841
+ throw new Error("请先通过enable初始化基础统计能力");
6275
6842
  }
6276
- formatKey.sort((a, b) => b - a);
6277
- let result = [];
6278
- let total = amount;
6279
- for (let i = 0; i < formatKey.length; i++) {
6280
- const key = formatKey[i];
6281
- let count = Math.floor(Math.abs(total / key)) * (total / Math.abs(total));
6282
- if (count == 0) {
6283
- continue;
6284
- }
6285
- total = total % key;
6286
- result.push(`${count}${format[key]}`);
6843
+ if (!this._pay) {
6844
+ this._pay = new PayAnalyticsAble(this.base);
6287
6845
  }
6288
- return result.length ? result.join("") : `${amount}`;
6846
+ return this._pay;
6289
6847
  }
6290
6848
  /**
6291
- * 带自动补全的秒数格式。
6292
- * @param second 秒数
6293
- * @param format 格式化文本
6294
- * @param pad 填充文本,默认为“0”
6295
- * @example
6296
- * formatSecond(86400, "ddd天hh小时mm分ss秒")=>"001天00小时00分00秒"
6297
- * formatSecond(86400, "dd天hh小时mm分ss秒")=>"01天00小时00分00秒"
6298
- * formatSecond(86400, "hh小时mm分ss秒")=>"24小时00分00秒"
6299
- * formatSecond(86400, "mm分ss秒")=>"1440分00秒"
6849
+ * 启用统计(基础统计能力)
6850
+ * @param debugMode 调试模式,是否打印日志信息,默认为false
6851
+ * @param senders 上报器列表,允许多个 默认为ALiAnalyticsSender
6300
6852
  * @returns
6301
6853
  */
6302
- static formatSecond(second, format, pad = "0") {
6303
- const formatArr = [
6304
- { unit: 86400, regExp: /D{2,}/i },
6305
- { unit: 3600, regExp: /H{1,2}/i },
6306
- { unit: 60, regExp: /m{1,2}/i },
6307
- { unit: 1, regExp: /s{1,2}/i },
6308
- ];
6309
- for (let i = 0; i < formatArr.length; i++) {
6310
- const element = formatArr[i];
6311
- let match = element.regExp.exec(format);
6312
- if (match) {
6313
- format = format.replace(element.regExp, Math.floor(second / element.unit).toFixed(0).padStart(match[0].length, pad));
6314
- second = second % element.unit;
6315
- }
6854
+ enable(debugMode = false, senders) {
6855
+ if (this.base.inited) {
6856
+ return;
6316
6857
  }
6317
- return format;
6858
+ senders = senders || this.createBehaviorSenders();
6859
+ this.base.init(senders, debugMode);
6860
+ this.launch.report("enabled");
6861
+ }
6862
+ get version() {
6863
+ return "v1";
6318
6864
  }
6319
6865
  /**
6320
- * 带自动补全的时间戳格式化
6321
- * @param milliseconds
6322
- * @param format
6323
- * @param pad 填充文本,默认为“0”
6324
- * @returns
6866
+ * 获取所有维度的数据
6867
+ * @returns 所有维度的数据
6325
6868
  */
6326
- static formatTimestamp(milliseconds, format, pad = "0") {
6327
- let date = new Date(milliseconds);
6328
- date.getHours();
6329
- const formatArr = [
6330
- { r: /Y{4}/, to: date.getFullYear() },
6331
- { r: /M{1,2}/, to: date.getMonth() + 1 },
6332
- { r: /D{1,2}/, to: date.getDate() },
6333
- { r: /H{1,2}/, to: date.getHours() },
6334
- { r: /m{1,2}/, to: date.getMinutes() },
6335
- { r: /s{1,2}/, to: date.getSeconds() },
6336
- ];
6337
- for (let i = 0; i < formatArr.length; i++) {
6338
- const element = formatArr[i];
6339
- let match = element.r.exec(format);
6340
- if (match) {
6341
- format = format.replace(element.r, element.to.toString().padStart(match[0].length, "0"));
6342
- }
6869
+ getMetrics() {
6870
+ const result = {};
6871
+ result[DimensionType[DimensionType.ACTIVITY]] = this.session.getMetrics();
6872
+ result[DimensionType[DimensionType.AD]] = this.ad.getMetrics();
6873
+ result[DimensionType[DimensionType.SOCIAL]] = this.social.getMetrics();
6874
+ return result;
6875
+ }
6876
+ get assignmentSender() {
6877
+ if (!this._assignmentSender) {
6878
+ const analyticsConfig = remoteConfigService.config(SystemOnlineConfig).getAssignmentConfig();
6879
+ this._assignmentSender = this.hasRelayUrl(analyticsConfig)
6880
+ ? new KeytopsAnalyticsSender(analyticsConfig, analyticsConfig.exclude || ["view"])
6881
+ : new EmptyAnalyticsSender();
6343
6882
  }
6344
- return format;
6883
+ return this._assignmentSender;
6884
+ }
6885
+ reportAssignments(resolveMeta, levelid) {
6886
+ if (!resolveMeta) {
6887
+ return;
6888
+ }
6889
+ const method = resolveMeta.method;
6890
+ if (!method) {
6891
+ throw new Error("method is required");
6892
+ }
6893
+ const eventName = `${method}_assignment`;
6894
+ (resolveMeta.matchedUnits || []).forEach((unit) => {
6895
+ const payload = {
6896
+ method: method,
6897
+ resolve_key: resolveMeta.resolveKey,
6898
+ config_name: unit.configName,
6899
+ fingerprint: unit.fingerprint,
6900
+ };
6901
+ if (unit.publishId) {
6902
+ payload.publish_id = unit.publishId;
6903
+ }
6904
+ if (unit.variantId) {
6905
+ payload.variant_id = unit.variantId;
6906
+ }
6907
+ if (unit.variantFingerprint) {
6908
+ payload.variant_fingerprint = unit.variantFingerprint;
6909
+ }
6910
+ if (levelid !== undefined) {
6911
+ payload.level_id = levelid;
6912
+ }
6913
+ this.assignmentSender.send(eventName, payload, {});
6914
+ });
6345
6915
  }
6346
6916
  }
6917
+ /**
6918
+ * 埋点统计能力
6919
+ */
6920
+ const analytics = new AnalyticsManager();
6347
6921
 
6348
6922
  class KKTServer {
6349
6923
  requestConfig(context) {
@@ -6462,7 +7036,6 @@ class Application {
6462
7036
  this.impl.launch();
6463
7037
  this._resetLaunchTimes();
6464
7038
  timer.enable();
6465
- analytics.enable(debug);
6466
7039
  let isFirstLaunch = this.isFirstLaunch;
6467
7040
  console.log(`App Launch Done. isFirstLaunch:${isFirstLaunch}`);
6468
7041
  });
@@ -6655,37 +7228,6 @@ Application.KEY = "Application";
6655
7228
  */
6656
7229
  const App = new Application();
6657
7230
 
6658
- /*
6659
- @name: NativeHelper
6660
- @desc: 原生函数调用代理
6661
- @author: timoo
6662
- @date: 2022/11/26
6663
- */
6664
- class NativeHelper {
6665
- static call(className, methodName, ...args) {
6666
- NativeHelper.impl.call(className, methodName, ...args);
6667
- }
6668
- static callWithReturnType(className, methodName, returnType, ...args) {
6669
- return NativeHelper.impl.callWithReturnType(className, methodName, returnType, ...args);
6670
- }
6671
- static registerCallback(caller, method, times, ...args) {
6672
- return NativeHelper.impl.registerCallback(caller, method, times, ...args);
6673
- }
6674
- static registerCallbackOnce(caller, method, ...args) {
6675
- return NativeHelper.impl.registerCallback(caller, method, 1, ...args);
6676
- }
6677
- static get impl() {
6678
- if (this._impl == null) {
6679
- this._impl = Injector.getInject(NativeHelper.KEY);
6680
- }
6681
- if (this._impl == null) {
6682
- throw new Error(NativeHelper.KEY + " 未注入!");
6683
- }
6684
- return this._impl;
6685
- }
6686
- }
6687
- NativeHelper.KEY = "NativeHelper";
6688
-
6689
7231
  /*
6690
7232
  @name: BusinessCenter
6691
7233
  @desc: 事务中心,管理事务
@@ -9811,15 +10353,18 @@ class IShareAble {
9811
10353
  let internalQuery = dataArr.join("&");
9812
10354
  return query ? query + "&" + internalQuery : internalQuery;
9813
10355
  }
9814
- _report(analyticsName, msg) {
9815
- let data = { msg };
10356
+ _report(analyticsName, phase, method = "text_or_image") {
10357
+ let data = { phase, method };
9816
10358
  if (typeof analyticsName === "string") {
9817
- data.name = analyticsName;
10359
+ data.itemId = analyticsName;
9818
10360
  }
9819
10361
  else if (typeof analyticsName == "object") {
9820
10362
  Object.assign(data, analyticsName);
10363
+ if (data.itemId === undefined && data.name !== undefined) {
10364
+ data.itemId = data.name;
10365
+ }
9821
10366
  }
9822
- analytics.social.recordShare(data);
10367
+ analytics.social.share(data);
9823
10368
  }
9824
10369
  /**
9825
10370
  * 分享图片或者文字
@@ -10558,9 +11103,12 @@ class NativeAnalyticsSender extends EmptyAnalyticsSender {
10558
11103
  this._className = "sdk.Share";
10559
11104
  this._className = className;
10560
11105
  }
10561
- send(eventName, data) {
11106
+ mapEvent(eventName, eventData) {
11107
+ return mapCanonicalEventToFlatName(eventName, eventData);
11108
+ }
11109
+ send(eventName, eventData, userProperties) {
10562
11110
  return new Promise((success) => {
10563
- NativeHelper.call(this._className, "report", eventName, JSON.stringify(data));
11111
+ NativeHelper.call(this._className, "report", eventName, JSON.stringify(Object.assign(Object.assign({}, userProperties), eventData)));
10564
11112
  success();
10565
11113
  });
10566
11114
  }
@@ -10831,14 +11379,14 @@ class NativeShare extends IShareAble {
10831
11379
  shareTextOrImage(analyticsName, data) {
10832
11380
  return __awaiter(this, void 0, void 0, function* () {
10833
11381
  console.log("发起分享:", analyticsName, data);
10834
- this._report(analyticsName, "发起");
11382
+ this._report(analyticsName, "begin");
10835
11383
  return this._share("textOrImage", analyticsName, data);
10836
11384
  });
10837
11385
  }
10838
11386
  shareVideo(analyticsName, data) {
10839
11387
  return __awaiter(this, void 0, void 0, function* () {
10840
11388
  console.log("发起视频分享:", analyticsName, data);
10841
- this._report(analyticsName, "发起");
11389
+ this._report(analyticsName, "begin", "video");
10842
11390
  return this._share("video", analyticsName, data);
10843
11391
  });
10844
11392
  }
@@ -10847,12 +11395,12 @@ class NativeShare extends IShareAble {
10847
11395
  let callbacks = [];
10848
11396
  callbacks.push(NativeHelper.registerCallbackOnce(this, () => {
10849
11397
  console.log("分享完成,分享是否成功:", true);
10850
- this._report(analyticsName, "成功");
11398
+ this._report(analyticsName, "success", action === "video" ? "video" : "text_or_image");
10851
11399
  resolve(true);
10852
11400
  }));
10853
11401
  callbacks.push(NativeHelper.registerCallbackOnce(this, () => {
10854
11402
  console.log("分享完成,分享是否成功:", false);
10855
- this._report(analyticsName, "失败");
11403
+ this._report(analyticsName, "fail", action === "video" ? "video" : "text_or_image");
10856
11404
  resolve(false);
10857
11405
  }));
10858
11406
  if (typeof data == "string") {
@@ -11297,10 +11845,13 @@ class TKAd extends IADAble {
11297
11845
  * TK事件上报器(window['tt'].reportAnalytics)
11298
11846
  */
11299
11847
  class TKAnalyticsSender extends EmptyAnalyticsSender {
11300
- send(eventName, data) {
11848
+ mapEvent(eventName, eventData) {
11849
+ return mapCanonicalEventToFlatName(eventName, eventData);
11850
+ }
11851
+ send(eventName, eventData, userProperties) {
11301
11852
  var _a, _b;
11302
11853
  return __awaiter(this, void 0, void 0, function* () {
11303
- (_b = (_a = window['TTMinis']) === null || _a === void 0 ? void 0 : _a.game) === null || _b === void 0 ? void 0 : _b.reportEvent(eventName, data);
11854
+ (_b = (_a = window['TTMinis']) === null || _a === void 0 ? void 0 : _a.game) === null || _b === void 0 ? void 0 : _b.reportEvent(eventName, Object.assign(Object.assign({}, userProperties), eventData));
11304
11855
  });
11305
11856
  }
11306
11857
  }
@@ -11322,9 +11873,12 @@ class WXPay extends IPayAble {
11322
11873
  * 微信事件上报器(window['wx'].reportEvent)
11323
11874
  */
11324
11875
  class WXAnalyticsSender extends EmptyAnalyticsSender {
11325
- send(eventName, data) {
11876
+ mapEvent(eventName, eventData) {
11877
+ return mapCanonicalEventToFlatName(eventName, eventData);
11878
+ }
11879
+ send(eventName, eventData, userProperties) {
11326
11880
  return __awaiter(this, void 0, void 0, function* () {
11327
- window['wx'].reportEvent(eventName, data);
11881
+ window['wx'].reportEvent(eventName, Object.assign(Object.assign({}, userProperties), eventData));
11328
11882
  });
11329
11883
  }
11330
11884
  }
@@ -11385,7 +11939,7 @@ class WXShare extends IShareAble {
11385
11939
  return __awaiter(this, void 0, void 0, function* () {
11386
11940
  return new Promise((resolve) => {
11387
11941
  console.log("发起分享:", analyticsName, data);
11388
- this._report(analyticsName, "发起");
11942
+ this._report(analyticsName, "begin");
11389
11943
  if (!this._wx) {
11390
11944
  console.error("wx接口不存在!");
11391
11945
  resolve(false);
@@ -11401,14 +11955,14 @@ class WXShare extends IShareAble {
11401
11955
  let duration = Math.floor((Date.now() - shareTime) / 1000);
11402
11956
  let shareResult = duration <= tempData.durationMax && duration >= tempData.durationMin;
11403
11957
  console.log("分享完成,分享是否成功:", shareResult);
11404
- this._report(analyticsName, "成功");
11958
+ this._report(analyticsName, shareResult ? "success" : "fail");
11405
11959
  resolve(shareResult);
11406
11960
  };
11407
11961
  App.onShow(onShareBack);
11408
11962
  }
11409
11963
  else {
11410
11964
  console.log("分享完成,分享是否成功:", false);
11411
- this._report(analyticsName, "失败");
11965
+ this._report(analyticsName, "fail");
11412
11966
  resolve(true);
11413
11967
  }
11414
11968
  });
@@ -12142,7 +12696,7 @@ class KSShare extends IShareAble {
12142
12696
  return __awaiter(this, void 0, void 0, function* () {
12143
12697
  return new Promise((resolve) => {
12144
12698
  console.log("发起分享:", data);
12145
- this._report(analyticsName, "发起");
12699
+ this._report(analyticsName, "begin");
12146
12700
  if (!this._ks) {
12147
12701
  console.error("快手接口不存在!");
12148
12702
  resolve(false);
@@ -12151,12 +12705,12 @@ class KSShare extends IShareAble {
12151
12705
  params.query = this._getShareQuery(analyticsName, params.query);
12152
12706
  params.success = () => {
12153
12707
  console.log("分享完成,分享是否成功:", true);
12154
- this._report(analyticsName, "成功");
12708
+ this._report(analyticsName, "success");
12155
12709
  resolve(true);
12156
12710
  };
12157
12711
  params.fail = (e) => {
12158
12712
  console.log("分享完成,分享是否成功:", false, e);
12159
- this._report(analyticsName, "失败");
12713
+ this._report(analyticsName, "fail");
12160
12714
  resolve(false);
12161
12715
  };
12162
12716
  this._ks.shareAppMessage(params);
@@ -12165,8 +12719,10 @@ class KSShare extends IShareAble {
12165
12719
  }
12166
12720
  shareVideo(analyticsName, data) {
12167
12721
  return __awaiter(this, void 0, void 0, function* () {
12168
- publisher.recordT().publicVideo(this._getShareQuery(analyticsName, data.query), data.mouldId);
12169
- return true;
12722
+ this._report(analyticsName, "begin", "video");
12723
+ const success = yield publisher.recordT().publicVideo(this._getShareQuery(analyticsName, data.query), data.mouldId);
12724
+ this._report(analyticsName, success ? "success" : "fail", "video");
12725
+ return success;
12170
12726
  });
12171
12727
  }
12172
12728
  }
@@ -12287,7 +12843,7 @@ class TTShare extends IShareAble {
12287
12843
  return __awaiter(this, void 0, void 0, function* () {
12288
12844
  return new Promise((resolve) => {
12289
12845
  console.log("发起分享:", data);
12290
- this._report(analyticsName, "发起");
12846
+ this._report(analyticsName, "begin");
12291
12847
  if (!this._tt) {
12292
12848
  console.error("tt接口不存在!");
12293
12849
  resolve(false);
@@ -12296,12 +12852,12 @@ class TTShare extends IShareAble {
12296
12852
  params.query = this._getShareQuery(analyticsName, params.query);
12297
12853
  params.success = () => {
12298
12854
  console.log("分享完成,分享是否成功:", true);
12299
- this._report(analyticsName, "成功");
12855
+ this._report(analyticsName, "success");
12300
12856
  resolve(true);
12301
12857
  };
12302
12858
  params.fail = (e) => {
12303
12859
  console.log("分享完成,分享是否成功:", false, e);
12304
- this._report(analyticsName, "失败");
12860
+ this._report(analyticsName, "fail");
12305
12861
  resolve(false);
12306
12862
  };
12307
12863
  this._tt.shareAppMessage(params);
@@ -12312,7 +12868,7 @@ class TTShare extends IShareAble {
12312
12868
  return __awaiter(this, void 0, void 0, function* () {
12313
12869
  return new Promise((resolve) => {
12314
12870
  console.log("发起视频分享:", data);
12315
- this._report(analyticsName, "发起");
12871
+ this._report(analyticsName, "begin", "video");
12316
12872
  if (!this._tt) {
12317
12873
  console.error("tt接口不存在!");
12318
12874
  resolve(false);
@@ -12329,12 +12885,12 @@ class TTShare extends IShareAble {
12329
12885
  },
12330
12886
  success: (res) => {
12331
12887
  console.log("分享完成,分享是否成功:", true);
12332
- this._report(analyticsName, "成功");
12888
+ this._report(analyticsName, "success", "video");
12333
12889
  resolve(true);
12334
12890
  },
12335
12891
  fail: (e) => {
12336
12892
  console.log("分享完成,分享是否成功:", false, e);
12337
- this._report(analyticsName, "失败");
12893
+ this._report(analyticsName, "fail", "video");
12338
12894
  resolve(false);
12339
12895
  },
12340
12896
  });
@@ -12700,9 +13256,12 @@ class TTAd extends IADAble {
12700
13256
  * 字节事件上报器(window['tt'].reportAnalytics)
12701
13257
  */
12702
13258
  class TTAnalyticsSender extends EmptyAnalyticsSender {
12703
- send(eventName, data) {
13259
+ mapEvent(eventName, eventData) {
13260
+ return mapCanonicalEventToFlatName(eventName, eventData);
13261
+ }
13262
+ send(eventName, eventData, userProperties) {
12704
13263
  return __awaiter(this, void 0, void 0, function* () {
12705
- window['tt'].reportAnalytics(eventName, data);
13264
+ window['tt'].reportAnalytics(eventName, Object.assign(Object.assign({}, userProperties), eventData));
12706
13265
  });
12707
13266
  }
12708
13267
  }
@@ -15161,4 +15720,4 @@ TipsView = __decorate([
15161
15720
  menu("基础视图/TipsView")
15162
15721
  ], TipsView);
15163
15722
 
15164
- export { ADAnalyticsAble, ADBehaviorReporter, ADEvent, ADType, AD_METRIC_ORDER_V1, ALiAnalyticsSender, AdDimension, AnalyticsAble, App, Application, Async, AudioBusiness, BaseDimension, BaseOnlineConfig, BaseProtocolHelper, BusinessCenter, ByteView, CCPViewLoader, CCSceneLoader, CocosNativeHelper, CocosStorageUtils, CocosViewManager, Component, ConfigHelper, DEFAULT_GAME_FLAG, Dictionary, DimensionType, ECS, EffectAudioSourceProxy, EmptyAnalyticsSender, EmptyLink, EnterOptionParser, Event$2 as Event, EventDispatcher, Fsm, FsmBase, GameDimension, GameLeaveType, GeometryUtils, Handler, HttpNode, HttpRequest, IADAble, IDevice, IGameUpdateAble, ILoginAble, INTERNAL_METHODS, INativeHelper, IPayAble, IPublisher, IPublisherManager, IRecordAble, IShareAble, IViewLoader, Injector, Json, KKTServer, KSAd, KSDevice, KSLogin, KSPublisher, KSRecorder, KSShare, KeytopsAnalyticsSender, LEVEL_STATS_METRIC_ORDER_V1, LaunchAnalyticsAble, LevelAnalyticsAble, LevelBehaviorReporter, LevelOnlineConfig, LevelStatsDimension, Link, List, LogType, Logger, MYAd, MYDevice, MYLogin, MYPublisher, Mask, MathUtils, MemeryStorage, NativeAd, NativeAnalyticsSender, NativeDevice, NativeHelper, NativeLogin, NativePay, NativePublisher, NativeRecorder, NativeShare, NativeUtils, NetManager, NoRequestServer, PLAYER_ABILITY_METRIC_ORDER_V1, PlayerAbilityDimension, Pool, PromiseUtils, PropSupport, PublisherManager, RemoteConfigService, RemoteConfigStore, ResourceManager, RewardVideoMaskBusiness, RuntimeApplicationImpl, Scene, Server, SessionAnalyticsAble, SessionDimension, SocialAnalyticsAble, SocialDimension, Socket, SocketLogType, SocketNode, Storage, StorageImpl, StringUtils, System, SystemOnlineConfig, TKAd, TKAnalyticsSender, TKDevice, TKLogin, TKPublisher, TTAd, TTAnalyticsSender, TTDevice, TTGameUpdater, TTLogin, TTPay, TTPublisher, TTRecorder, TTShare, Task, TaskQueue, TaskSequence, Timer, TimerImpl, TipsType, TipsView, View, ViewControl, ViewLevel, ViewManager, WXAd, WXAnalyticsSender, WXDevice, WXGameUpdater, WXLogin, WXPay, WXPublisher, WXShare, ab, analytics, audio, bidding, businessCenter, cmd, component, eventCenter, fsmManager, manager, maskView, md5, net, publisher, remoteConfig, remoteConfigService, res, server, storage, system, timer, version, viewAnalytics, viewClass, viewManager };
15723
+ export { ADAnalyticsAble, ADBehaviorReporter, ADEvent, ADType, AD_METRIC_ORDER_V1, ALiAnalyticsSender, AdDimension, AnalyticsAble, AnalyticsBehavior, App, Application, Async, AudioBusiness, BaseDimension, BaseOnlineConfig, BaseProtocolHelper, BusinessCenter, ByteView, CCPViewLoader, CCSceneLoader, CocosNativeHelper, CocosStorageUtils, CocosViewManager, Component, ConfigHelper, DEFAULT_GAME_FLAG, Dictionary, DimensionType, ECS, EffectAudioSourceProxy, EmptyAnalyticsSender, EmptyLink, EnterOptionParser, Event$2 as Event, EventDispatcher, FirebaseAnalyticsSender, Fsm, FsmBase, GameDimension, GameLeaveType, GeometryUtils, Handler, HttpNode, HttpRequest, IADAble, IDevice, IGameUpdateAble, ILoginAble, INTERNAL_METHODS, INativeHelper, IPayAble, IPublisher, IPublisherManager, IRecordAble, IShareAble, IViewLoader, Injector, Json, KKTServer, KSAd, KSDevice, KSLogin, KSPublisher, KSRecorder, KSShare, KeytopsAnalyticsSender, LEVEL_STATS_METRIC_ORDER_V1, LaunchAnalyticsAble, LevelAnalyticsAble, LevelBehaviorReporter, LevelOnlineConfig, LevelStatsDimension, Link, List, LogType, Logger, MYAd, MYDevice, MYLogin, MYPublisher, Mask, MathUtils, MemeryStorage, NativeAd, NativeAnalyticsSender, NativeDevice, NativeHelper, NativeLogin, NativePay, NativePublisher, NativeRecorder, NativeShare, NativeUtils, NetManager, NoRequestServer, PLAYER_ABILITY_METRIC_ORDER_V1, PayAnalyticsAble, PlayerAbilityDimension, Pool, PromiseUtils, PropSupport, PublisherManager, RemoteConfigService, RemoteConfigStore, ResourceManager, RewardVideoMaskBusiness, RuntimeApplicationImpl, Scene, Server, SessionAnalyticsAble, SessionDimension, SocialAnalyticsAble, SocialDimension, Socket, SocketLogType, SocketNode, Storage, StorageImpl, StringUtils, System, SystemOnlineConfig, TKAd, TKAnalyticsSender, TKDevice, TKLogin, TKPublisher, TTAd, TTAnalyticsSender, TTDevice, TTGameUpdater, TTLogin, TTPay, TTPublisher, TTRecorder, TTShare, Task, TaskQueue, TaskSequence, Timer, TimerImpl, TipsType, TipsView, TutorialAnalyticsAble, View, ViewControl, ViewLevel, ViewManager, WXAd, WXAnalyticsSender, WXDevice, WXGameUpdater, WXLogin, WXPay, WXPublisher, WXShare, ab, analytics, audio, bidding, businessCenter, cmd, component, eventCenter, fsmManager, manager, mapCanonicalEventToFlatName, mapCanonicalEventToLegacy, maskView, md5, net, publisher, remoteConfig, remoteConfigService, res, server, storage, system, timer, version, viewAnalytics, viewClass, viewManager };