From 4096960d556b40589ef9eb2c24a5665696a1fa4c Mon Sep 17 00:00:00 2001 From: devin-cwd Date: Thu, 15 Aug 2024 20:23:12 +0800 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20=E4=BA=8B=E4=BB=B6=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AD=97=E6=AE=B5=E4=BB=8Edata=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=E4=B8=BAproperties=EF=BC=9B=E4=BF=AE=E5=A4=8D=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E8=87=AA=E8=BF=90=E8=A1=8Cstorage=EF=BC=8C=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E6=9C=8D=E5=8A=A1=E7=AB=AF=E6=B8=B2=E6=9F=93=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/analytics/src/events/click.ts | 1 - packages/analytics/src/events/index.ts | 1 - packages/analytics/src/open-analytics.ts | 184 ++++++++++++----------- packages/analytics/src/storage.ts | 7 +- packages/analytics/src/types.ts | 3 +- packages/analytics/test/main.ts | 2 +- 6 files changed, 102 insertions(+), 96 deletions(-) diff --git a/packages/analytics/src/events/click.ts b/packages/analytics/src/events/click.ts index 2761d54..a2ba36d 100644 --- a/packages/analytics/src/events/click.ts +++ b/packages/analytics/src/events/click.ts @@ -30,7 +30,6 @@ export default { clearTimeout(debounceId); debounceId = globalThis.setTimeout(async () => { const data = await handleClick(e, customData); - console.log(data); resolve(data); }, delay); diff --git a/packages/analytics/src/events/index.ts b/packages/analytics/src/events/index.ts index c200c7b..31a41b3 100644 --- a/packages/analytics/src/events/index.ts +++ b/packages/analytics/src/events/index.ts @@ -1,4 +1,3 @@ -import { OpenEventKeys } from './_keys'; import { EventContent } from '../types'; import { isFunction } from '../utils'; diff --git a/packages/analytics/src/open-analytics.ts b/packages/analytics/src/open-analytics.ts index 48d017b..ff2aab5 100644 --- a/packages/analytics/src/open-analytics.ts +++ b/packages/analytics/src/open-analytics.ts @@ -25,7 +25,14 @@ class AnalyticsStoreKey { } type StoreKeyIns = InstanceType; -const store = new Storage(localStorage); +let store: InstanceType; +/** + * 初始化存储器 + * @param appId {string} + */ +function initStorage(target?: globalThis.Storage) { + store = new Storage(target || globalThis.localStorage); +} /** * 初始化通用数据 @@ -77,56 +84,73 @@ function getSessionId(sKey: string) { } export class OpenAnalytics { - request: ReportRequest; - eventData: EventData[]; - immediate: boolean; - sessionId: string = ''; - appKey: string = ''; - header: EventHeader; enabled: boolean; - StoreKey: StoreKeyIns; - // 自定义上报策略 - requestPlan?: (requestFn: () => void) => void; - // 上报间隔,默认3s - requestInterval: number; - maxEvents: number; #timer: number | null; #firstReport: boolean; + #request: ReportRequest; + #eventData: EventData[]; + #immediate: boolean; + #sessionId: string = ''; + #appKey: string = ''; + #header: EventHeader; + #StoreKey: StoreKeyIns; + // 自定义上报策略 + #requestPlan?: (requestFn: () => void) => void; + // 上报间隔,默认3s + #requestInterval: number; + #maxEvents: number; /** * 构造函数 * @param params {OpenAnalyticsParams} */ constructor(params: OpenAnalyticsParams) { - this.request = params.request; - this.immediate = params.immediate ?? false; - this.appKey = params.appKey ?? ''; - this.StoreKey = new AnalyticsStoreKey(params.appKey); - this.requestInterval = params.requestInterval ?? Constant.DEFAULT_REQUEST_INTERVAL; + initStorage(); + this.#request = params.request; + this.#immediate = params.immediate ?? false; + this.#appKey = params.appKey ?? ''; + this.#StoreKey = new AnalyticsStoreKey(params.appKey); + this.#requestInterval = params.requestInterval ?? Constant.DEFAULT_REQUEST_INTERVAL; this.#timer = null; - this.maxEvents = params.maxEvents ?? Constant.MAX_EVENTS; + this.#maxEvents = params.maxEvents ?? Constant.MAX_EVENTS; this.#firstReport = true; - this.enabled = store.get(this.StoreKey.enabled).value === Constant.OA_ENABLED; + this.enabled = store.get(this.#StoreKey.enabled).value === Constant.OA_ENABLED; if (this.enabled) { - store.set(this.StoreKey.enabled, Constant.OA_ENABLED); - this.eventData = store.getAlways(this.StoreKey.events, { + store.set(this.#StoreKey.enabled, Constant.OA_ENABLED); + this.#eventData = store.getAlways(this.#StoreKey.events, { defaultValue: () => [], }).value; - this.header = initHeader(this.StoreKey, this.appKey); + this.#header = initHeader(this.#StoreKey, this.#appKey); } else { - this.header = {}; - this.eventData = []; - store.remove(this.StoreKey.events); + this.#header = {}; + this.#eventData = []; + store.remove(this.#StoreKey.events); + } + } + /** + * 搜集数据 + */ + #collect(data: EventData, immediate?: boolean) { + this.#eventData.push(data); + + // 如果事件数超过最大数量,丢弃之前的事件 + if (this.#eventData.length > this.#maxEvents) { + this.#eventData.shift(); + } + if (this.enabled) { + store.set(this.#StoreKey.events, this.#eventData); + + this.runRequestPlan(immediate); } } /** * 设置header */ setHeader(header: Record) { - Object.assign(this.header, header); + Object.assign(this.#header, header); } /** * 控制是否发送数据上报 @@ -138,65 +162,77 @@ export class OpenAnalytics { } if (this.enabled) { - store.set(this.StoreKey.enabled, Constant.OA_ENABLED); - this.header = Object.assign(initHeader(this.StoreKey, this.appKey), this.header); + store.set(this.#StoreKey.enabled, Constant.OA_ENABLED); + this.#header = Object.assign(initHeader(this.#StoreKey, this.#appKey), this.#header); // 初始化sessionId - this.sessionId = getSessionId(this.StoreKey.session); + this.#sessionId = getSessionId(this.#StoreKey.session); // 给内存中事件添加sessionId - this.eventData.forEach((event) => { + this.#eventData.forEach((event) => { if (event.sId === '') { - event.sId = this.sessionId; + event.sId = this.#sessionId; } }); // 将数据存储到本地 - store.set(this.StoreKey.events, this.eventData); + store.set(this.#StoreKey.events, this.#eventData); // 执行上报策略 this.runRequestPlan(); } else if (this.#timer) { clearTimeout(this.#timer); this.#timer = 0; - this.eventData = []; - store.remove(this.StoreKey.enabled); - store.remove(this.StoreKey.events); - store.remove(this.StoreKey.client); - store.remove(this.StoreKey.session); + this.#eventData = []; + store.remove(this.#StoreKey.enabled); + store.remove(this.#StoreKey.events); + store.remove(this.#StoreKey.client); + store.remove(this.#StoreKey.session); } } /** - * 搜集数据 + * 采集数据 + * @param event 事件名 + * @param data 事件数据,如果是内部事件,则会在内部事件触发时执行 + * @param options 配置 */ - collect(data: EventData, immediate?: boolean) { - this.eventData.push(data); - - // 如果事件数超过最大数量,丢弃之前的事件 - if (this.eventData.length > this.maxEvents) { - this.eventData.shift(); + async report(event: string, content?: (...opts: any[]) => Promise | EventContent, collectOptions?: CollectorOptions, immediate?: boolean) { + if (!event) { + return; } - if (this.enabled) { - store.set(this.StoreKey.events, this.eventData); - this.runRequestPlan(immediate); + let reportData: EventContent = {}; + + if (isInnerEvent(event)) { + reportData = (await getInnerEventData(event, collectOptions)) || {}; + } else if (content) { + reportData = await content(); } + + const eventData: EventData = { + event: event, + time: Date.now(), + properties: reportData, + sId: this.enabled ? getSessionId(this.#StoreKey.session) : '', + }; + + this.#collect(eventData, immediate); } /** * 执行上报策略 * @param immediate */ runRequestPlan(immediate?: boolean) { - if (immediate || this.immediate) { + if (immediate || this.#immediate) { this.doSendEventData(); } else if (this.#firstReport) { this.#firstReport = false; whenDocumentReady(() => this.doSendEventData()); } else { - if (isFunction(this.requestPlan)) { - this.requestPlan(this.doSendEventData); + if (isFunction(this.#requestPlan)) { + this.#requestPlan(this.doSendEventData); } else { const run = () => { this.#timer = window.setTimeout(() => { this.doSendEventData(); run(); - }, this.requestInterval); + }, this.#requestInterval); }; if (!this.#timer) { run(); @@ -208,52 +244,24 @@ export class OpenAnalytics { * 发起数据上报 */ doSendEventData() { - if (!this.request || !this.enabled || this.eventData.length === 0) { + if (!this.#request || !this.enabled || this.#eventData.length === 0) { return; } const reportData = { - header: this.header, - body: this.eventData, + header: this.#header, + body: this.#eventData, }; - const rlt = this.request(reportData); + const rlt = this.#request(reportData); if (isPromise(rlt)) { rlt.then((isSuccess) => { if (isSuccess) { - this.eventData = []; - store.set(this.StoreKey.events, []); + this.#eventData = []; + store.set(this.#StoreKey.events, []); } }); } else { - this.eventData = []; - store.set(this.StoreKey.events, []); - } - } - /** - * 采集数据 - * @param event 事件名 - * @param data 事件数据,如果是内部事件,则会在内部事件触发时执行 - * @param options 配置 - */ - async report(event: string, content?: (...opts: any[]) => Promise | EventContent, collectOptions?: CollectorOptions, immediate?: boolean) { - if (!event) { - return; + this.#eventData = []; + store.set(this.#StoreKey.events, []); } - - let reportData: EventContent = {}; - - if (isInnerEvent(event)) { - reportData = (await getInnerEventData(event, collectOptions)) || {}; - } else if (content) { - reportData = await content(); - } - - const eventData: EventData = { - event: event, - time: Date.now(), - data: reportData, - sId: this.enabled ? getSessionId(this.StoreKey.session) : '', - }; - - this.collect(eventData, immediate); } } diff --git a/packages/analytics/src/storage.ts b/packages/analytics/src/storage.ts index f549e44..b58abe2 100644 --- a/packages/analytics/src/storage.ts +++ b/packages/analytics/src/storage.ts @@ -1,6 +1,5 @@ import { isFunction } from './utils'; -type StorageInstance = typeof localStorage | typeof sessionStorage; interface StorageSetOptions { expire?: number; once?: boolean; @@ -10,10 +9,10 @@ interface StorageOptions { checkExpiration?: (time: number) => boolean; } export class Storage { - store: StorageInstance = localStorage; + store: globalThis.Storage = globalThis.localStorage; checkExpiration: (expire: number) => boolean; - constructor(storage: StorageInstance, options?: StorageOptions) { - this.store = storage; + constructor(target: globalThis.Storage, options?: StorageOptions) { + this.store = target; this.checkExpiration = isFunction(options?.checkExpiration) ? options?.checkExpiration : (time: number) => { diff --git a/packages/analytics/src/types.ts b/packages/analytics/src/types.ts index d5e4dac..8bf195b 100644 --- a/packages/analytics/src/types.ts +++ b/packages/analytics/src/types.ts @@ -5,7 +5,7 @@ export type EventContent = { export interface EventData { event: string; // 事件名 time: number; // 事件采集时间 - data: EventContent; // 上报的事件数据 + properties: EventContent; // 上报的事件数据 sId: string; // 会话id } @@ -39,5 +39,6 @@ export interface OpenAnalyticsParams { immediate?: boolean; // 全局设置是否立即上报 requestInterval?: number; //上报间隔 maxEvents?: number; + storage?: typeof localStorage | typeof sessionStorage; requestPlan?: (requestFn: () => void) => void; } diff --git a/packages/analytics/test/main.ts b/packages/analytics/test/main.ts index de4b7cb..2655088 100644 --- a/packages/analytics/test/main.ts +++ b/packages/analytics/test/main.ts @@ -16,7 +16,7 @@ const oa = new OpenAnalytics({ }, // immediate: true, }); - +console.log(oa); oa.setHeader(getClientInfo()); function enabledOA(enabled) { -- Gitee From 71e89525405a1ba02ee3593deb22c8d014849cd8 Mon Sep 17 00:00:00 2001 From: devin-cwd Date: Thu, 15 Aug 2024 20:24:49 +0800 Subject: [PATCH 2/2] Release v5 --- packages/analytics/README.md | 5 +++++ packages/analytics/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/analytics/README.md b/packages/analytics/README.md index 292e406..b74ce25 100644 --- a/packages/analytics/README.md +++ b/packages/analytics/README.md @@ -17,3 +17,8 @@ 1. 新增内部事件:PageClick 页面点击事件;可用于热力图分析; 2. client 信息默认不提供,通过插件函数方式配置; 3. report 接口参数 event 不能为空; + +# 0.0.5 + +1. 事件数据字段从 data 更改为 properties; +2. 修复导入时自运行 storage,导致服务端渲染报错问题; diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 7df0379..a2f3cbf 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -1,6 +1,6 @@ { "name": "@opensig/open-analytics", - "version": "0.0.4", + "version": "0.0.5", "description": "opendesign analytics", "main": "dist/open-analytics.mjs", "types": "dist/open-analytics.d.ts", -- Gitee