UNPKG

@yqg/multiple-click

Version:

Monitor user's multiple click behavior and report

156 lines (155 loc) 7.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.processTrackingConfig = void 0; const constant_1 = require("./constant"); const type_1 = require("./type"); const utils_1 = require("./utils"); const getTrackingUrl = ({ env }) => { let trackingHost; if (env === type_1.ENV_TYPE.PROD_INDO) { trackingHost = constant_1.EVENT_TRACKING_HOST_PROD_INDO; } else if (env.startsWith('prod')) { trackingHost = constant_1.EVENT_TRACKING_HOST_PROD; } else if (env !== type_1.ENV_TYPE.DEV) { trackingHost = constant_1.EVENT_TRACKING_HOST_TEST; } const trackingUrl = trackingHost ? `${trackingHost}/logMetrics` : null; return trackingUrl; }; const fetchRemoteConfig = ({ appId, env }) => { const configCenterHost = constant_1.CONFIG_CENTER_HOST_MAP[env]; if (!configCenterHost) { return Promise.resolve({}); } const configUrl = `${configCenterHost}/api-web/hostCond?app=web-multiple-click&prefix=${appId}`; return fetch(configUrl) .then((res) => __awaiter(void 0, void 0, void 0, function* () { var _a, _b; const data = (_b = (_a = (yield res.json())) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b[appId]; const config = data ? JSON.parse(data) : {}; return (0, utils_1.pick)(config, ['disabled', 'interval', 'continuousCount', 'range', 'excludeRules']); })) .catch(() => ({})); }; const uploadTrackingInfoFactory = (config) => { const { appId, appVersion, customTrackingInfo } = config; const trackingUrl = getTrackingUrl(config); const osType = (0, utils_1.getOsType)(); const headers = { Country: (0, utils_1.getCountry)(), 'YQG-PLATFORM-SDK-TYPE': appId, 'CONTENT-TYPE': 'application/json;charset=UTF-8' }; const extraInfoGetter = ({ target: _target }) => { const target = _target; const { outerHTML } = target; const { x: clientLeft, y: clientTop } = target.getBoundingClientRect(); return { url: location.href, outerHTML: outerHTML.slice(0, constant_1.OUTER_HTML_MAX_LENGTH), selector: (0, utils_1.htmlTreeAsString)(target), offsetTop: clientTop + window.scrollY, offsetLeft: clientLeft + window.scrollX, clientTop, clientLeft }; }; const uploadTrackingInfo = (event) => { const trackingInfo = customTrackingInfo(event, extraInfoGetter(event)); if (!trackingUrl) { console.info('无需上报多次点击事件,事件信息:', trackingInfo); return; } const info = { level: 'INFO', logs: [ { appId, appVersion: appVersion || null, osType, measurement: 'app_metrics_for_multiple_click', metricsType: 'metricsType1', time: Date.now().toString(), message: 'multiple click', parameter: trackingInfo } ] }; fetch(trackingUrl, { method: 'post', headers, body: JSON.stringify(info) }).catch(err => console.error('多次点击上报异常', err)); }; return uploadTrackingInfo; }; const processTrackingConfig = (config) => __awaiter(void 0, void 0, void 0, function* () { const _a = yield fetchRemoteConfig(config), { disabled } = _a, remoteConfig = __rest(_a, ["disabled"]); if (disabled) { return null; } const defaultConfig = { interval: constant_1.DEFAULT_TRIGGER_INTERVAL, continuousCount: constant_1.DEFAULT_TRIGGER_CONTINUOUS_COUNT, range: constant_1.DEFAULT_TRIGGER_RANGE, customTrackingInfo: (_, extra) => extra, filter: () => false }; const mergedConfig = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultConfig), config), remoteConfig), { excludeRules: [...(0, utils_1.castArray)(config.excludeRules || []), ...(0, utils_1.castArray)(remoteConfig.excludeRules || [])] }); const { appId, appVersion, env, interval, continuousCount, range, customTrackingInfo, filter, excludeRules } = mergedConfig; if (typeof appId !== 'string' || !appId) { throw new Error('appId需为非空字符串'); } if (appVersion && typeof appVersion !== 'string') { throw new Error('appVersion需为字符串'); } const envTypeList = Object.values(type_1.ENV_TYPE); if (!envTypeList.includes(env)) { throw new Error(`env需为${envTypeList.join('、')}中的一个`); } if (typeof interval !== 'number' || interval <= 0) { throw new Error('interval需为大于0的数字'); } if (typeof continuousCount !== 'number' || continuousCount <= 1) { throw new Error('continuousCount需为大于1的数字'); } if (typeof range !== 'number' || range <= 0) { throw new Error('range需为大于0的数字'); } if (typeof customTrackingInfo !== 'function') { throw new Error('customTrackingInfo需为函数'); } if (typeof filter !== 'function') { throw new Error('filter需为函数'); } const validatedConfig = Object.assign(Object.assign({}, config), { interval, continuousCount, range, customTrackingInfo, filter }); const uploadTrackingInfo = uploadTrackingInfoFactory(validatedConfig); const parsedExcludeRules = excludeRules.map((_a) => { var { page } = _a, rule = __rest(_a, ["page"]); return (Object.assign(Object.assign({}, rule), { page: page ? (0, utils_1.castArray)(page) : [] })); }); return { interval, continuousCount, range, uploadTrackingInfo, filter, excludeRules: parsedExcludeRules }; }); exports.processTrackingConfig = processTrackingConfig;