gemercheung 2 年之前
父节点
当前提交
69bad95dcd

+ 1 - 1
README.md

@@ -99,7 +99,7 @@ medici.resume();
 ### 一次消费埋点
 
 ```js
-medici.track("BuyProduct", {
+const res = await medici.track("BuyProduct", {
   eventType:"click",
   ProductName: "MacBook Pro",
   ProductPrice: 123.45,

+ 8 - 8
package.json

@@ -17,17 +17,17 @@
         "docs": "pnpm typedoc --plugin none --lightHighlightTheme light-plus --entryPointStrategy packages ."
     },
     "devDependencies": {
-        "@changesets/cli": "^2.24.4",
-        "@typescript-eslint/eslint-plugin": "^5.36.2",
-        "@typescript-eslint/parser": "^5.36.2",
-        "doctoc": "~2.2.0",
+        "@changesets/cli": "^2.26.1",
+        "@typescript-eslint/eslint-plugin": "^5.59.5",
+        "@typescript-eslint/parser": "^5.59.5",
+        "doctoc": "~2.2.1",
         "eslint": "~8.19.0",
-        "eslint-config-prettier": "^8.5.0",
+        "eslint-config-prettier": "^8.8.0",
         "eslint-plugin-import": "~2.26.0",
         "eslint-plugin-prettier": "^4.2.1",
-        "prettier": "^2.7.1",
-        "typedoc": "^0.23.14",
-        "typedoc-plugin-markdown": "^3.13.6",
+        "prettier": "^2.8.8",
+        "typedoc": "^0.23.28",
+        "typedoc-plugin-markdown": "^3.15.3",
         "typescript": "~4.7.4"
     },
     "pnpm": {

+ 3 - 2
packages/core/package.json

@@ -18,8 +18,9 @@
     "prepublishOnly": "pnpm run build"
   },
   "dependencies": {
-    "@medici/types": "workspace:^0.0.4",
-    "@medici/utils": "workspace:^0.0.4"
+    "@medici/types": "workspace:^0.0.5",
+    "@medici/utils": "workspace:^0.0.4",
+    "@rollup/plugin-json": "^6.0.0"
   },
   "devDependencies": {
     "@rollup/plugin-typescript": "~8.3.4",

+ 2 - 0
packages/core/rollup.config.js

@@ -1,12 +1,14 @@
 import typescript from '@rollup/plugin-typescript';
 import { terser } from 'rollup-plugin-terser';
 import pkg from './package.json';
+import json from '@rollup/plugin-json';
 
 export default [
     {
         input: 'src/index.ts',
         external: Object.keys(pkg.dependencies),
         plugins: [
+            json(),
             typescript({
                 tsconfig: './tsconfig.build.json',
             }),

+ 48 - 20
packages/core/src/basicTrack.ts

@@ -1,9 +1,9 @@
-import { IBaseAction, ICustomAction, TrackActionOption, TrackEntityType } from '@medici/types';
+import { EventReturnType, EventReturnBooleanType, IBaseAction, ICustomAction, TrackActionOption, TrackEntityType } from '@medici/types';
 import type { SDKInitConfig, PlatformType, SDKConfigType } from './sdk';
 import type { IHistory } from './history';
 import { collect } from './collector';
 // import cloneDeep from 'lodash-es/cloneDeep';
-import { cloneDeep } from '@medici/utils';
+import { cloneDeep, getNetworkType } from '@medici/utils';
 
 import { SDK } from './sdk';
 
@@ -42,7 +42,8 @@ export class BaseTrack implements IBaseAction, ICustomAction {
             module: params.module,
             type: params.type,
             url: params.url || this._history.playload.url,
-            eventType: params.eventType,
+            // eventType: params.eventType,
+            event: params.event,
             referrer: params.referrer || this._history.currentRef,
             requestData: params.requestData,
         };
@@ -51,6 +52,8 @@ export class BaseTrack implements IBaseAction, ICustomAction {
         }
         if (params.networkType) {
             entity['networkType'] = params.networkType;
+        } else {
+            entity['networkType'] = getNetworkType();
         }
         if (params.userId) {
             entity['userId'] = params.userId;
@@ -58,21 +61,16 @@ export class BaseTrack implements IBaseAction, ICustomAction {
         return entity;
     }
 
-    public trackView(url: string, referrer: string, uuid: string): Promise<XMLHttpRequestResponseType> {
+    public trackView(url: string, referrer: string, uuid: string): EventReturnType {
         console.log('BaseTrack-trackView', url, referrer, uuid);
         if (!this._stopTrack) {
             this._history.playload.url = url;
             const historyPlayload = cloneDeep(this._history.playload);
-            // const payload = Object.assign(historyPlayload, {
-            //     ...this._config,
-            //     referrer: this._history.currentRef,
-            //     url: url,
-            // });
             const payload: TrackEntityType = {
                 module: 'pageview',
                 url: url,
                 type: 'pageview',
-                eventType: 'pageview',
+                event: 'pageview',
                 language: historyPlayload.language,
                 userId: this._config.user,
             };
@@ -81,7 +79,7 @@ export class BaseTrack implements IBaseAction, ICustomAction {
         }
     }
 
-    public trackEvent(event_name: string, event_data: string, url?: string, uuid?: string): Promise<XMLHttpRequestResponseType> {
+    public trackEvent(event_name: string, event_data: string, url?: string, uuid?: string): EventReturnType {
         if (!this._stopTrack) {
             console.log('BaseTrack-TrackEvent', event_name, event_data, url, uuid);
             this._history.playload.url = url;
@@ -98,7 +96,7 @@ export class BaseTrack implements IBaseAction, ICustomAction {
                 module: event_name,
                 url: url,
                 type: 'event',
-                eventType: event_data,
+                event: event_data,
                 language: historyPlayload.language,
                 userId: this._config.user,
             };
@@ -107,38 +105,68 @@ export class BaseTrack implements IBaseAction, ICustomAction {
         }
     }
 
-    public track(trackActionName: string, trackActionOption?: TrackActionOption): Promise<XMLHttpRequestResponseType> {
+    trackBeacon(trackActionName: string, trackActionOption?: TrackActionOption): EventReturnBooleanType {
         if (!this._stopTrack) {
             const historyPlayload = cloneDeep(this._history.playload);
             const trackObj = cloneDeep(trackActionOption);
-            delete trackObj.eventType;
+            delete trackObj.event;
+            delete trackObj.maxWaitTime;
+
+            const payload: TrackEntityType = {
+                module: trackActionName,
+                type: 'track',
+                event: trackActionOption.event,
+                requestData: Object.assign({ screen: historyPlayload.screen }, trackObj, this._config),
+                language: historyPlayload.language,
+                networkType: trackActionOption.networkType,
+                userId: this._config.user,
+            };
+            // this.toTrackEntity(payload);
+            if ('sendBeacon' in navigator) {
+                const blob = new Blob([JSON.stringify(payload)], {
+                    type: 'application/json; charset=UTF-8',
+                });
+
+                const isSend = navigator.sendBeacon(this.trackUrl, blob);
+                return Promise.resolve(isSend);
+            }
+            return Promise.resolve(false);
+        }
+    }
+
+    public track(trackActionName: string, trackActionOption?: TrackActionOption): EventReturnType {
+        if (!this._stopTrack) {
+            const historyPlayload = cloneDeep(this._history.playload);
+            const trackObj = cloneDeep(trackActionOption);
+            delete trackObj.event;
             delete trackObj.maxWaitTime;
 
             const payload: TrackEntityType = {
                 module: trackActionName,
                 type: 'track',
-                eventType: trackActionOption.eventType,
+                event: trackActionOption.event,
                 requestData: Object.assign({ screen: historyPlayload.screen }, trackObj, this._config),
                 language: historyPlayload.language,
                 networkType: trackActionOption.networkType,
                 userId: this._config.user,
             };
+            console.log('track-payload', payload);
             // this.toTrackEntity(payload);
             return collect(this.trackUrl, 'track', this.toTrackEntity(payload));
         }
     }
 
-    public startTrack(trackActionName: string, trackActionOption?: TrackActionOption): Promise<XMLHttpRequestResponseType> {
+    public startTrack(trackActionName: string, trackActionOption?: TrackActionOption): EventReturnType {
         if (!this._stopTrack) {
             const historyPlayload = cloneDeep(this._history.playload);
             const trackObj = cloneDeep(trackActionOption);
-            delete trackObj.eventType;
+            delete trackObj.event;
             delete trackObj.maxWaitTime;
 
             const payload: TrackEntityType = {
                 module: trackActionName,
                 type: 'start_track',
-                eventType: trackActionOption.eventType,
+                event: trackActionOption.event,
                 requestData: Object.assign({}, trackObj, this._config),
                 language: historyPlayload.language,
                 networkType: trackActionOption.networkType,
@@ -153,7 +181,7 @@ export class BaseTrack implements IBaseAction, ICustomAction {
         }
     }
 
-    public endTrack(trackActionName: string, trackActionOption?: TrackActionOption): Promise<XMLHttpRequestResponseType> {
+    public endTrack(trackActionName: string, trackActionOption?: TrackActionOption): EventReturnType {
         this._timeOut && clearTimeout(this._timeOut);
         if (!this._stopTrack) {
             const historyPlayload = cloneDeep(this._history.playload);
@@ -164,7 +192,7 @@ export class BaseTrack implements IBaseAction, ICustomAction {
             const payload: TrackEntityType = {
                 module: trackActionName,
                 type: 'end_track',
-                eventType: trackActionOption.eventType,
+                event: trackActionOption.event,
                 requestData: Object.assign({}, trackObj, this._config),
                 language: historyPlayload.language,
                 networkType: trackActionOption.networkType,

+ 5 - 2
packages/core/src/sdk.ts

@@ -3,6 +3,7 @@
 import { BaseTrack } from './basicTrack';
 import { IHistory } from './history';
 import { Eventer } from './event';
+import { version } from '../package.json';
 
 export type PlatformType = 'web' | 'miniApp';
 
@@ -22,7 +23,7 @@ export interface SDKConfigType {
 export class SDK extends BaseTrack {
     protected _platform: PlatformType;
     protected _config: SDKInitConfig;
-
+    protected _version: string;
     public eventer = new Eventer(this);
     public _history: IHistory;
 
@@ -32,14 +33,16 @@ export class SDK extends BaseTrack {
 
         this._history = new IHistory(this, params.appId);
         super._history = this._history;
+        this._version = version;
         if ('stopTrack' in params) {
             BaseTrack._stopTrack = params.stopTrack;
         }
         this.setConfig(params.config);
         //
     }
+    //true 正在追踪
     get trackStatus() {
-        return BaseTrack._stopTrack;
+        return !BaseTrack._stopTrack;
     }
     public setConfig(config: SDKInitConfig): void {
         this._config = Object.assign({ user: '', version: '' }, config);

+ 2 - 0
packages/core/src/xhr.ts

@@ -10,7 +10,9 @@ export const makeXHRRequest = (options: BrowserTransportOptions): Promise<XMLHtt
         xhr.setRequestHeader('Content-Type', 'application/json');
         xhr.onerror = reject;
         xhr.onreadystatechange = (): void => {
+            // console.log('xhr', xhr)
             if (xhr.readyState === 4) {
+                // console.log('xhr', xhr.response)
                 resolve(xhr.response);
             }
         };

+ 2 - 1
packages/core/tsconfig.build.json

@@ -2,10 +2,11 @@
   "extends": "../../tsconfig.build.json",
 
   "compilerOptions": {
+    "rootDir": "./",
     "outDir": "./dist"
   },
 
   "include": [
-    "src/**/*"
+    "src/**/*",
   ]
 }

+ 1 - 1
packages/legacy/package.json

@@ -28,7 +28,7 @@
         "typescript": "~4.7.4"
     },
     "dependencies": {
-        "@medici/core": "workspace:^0.0.9",
+        "@medici/core": "workspace:^0.1.0",
         "@medici/utils": "workspace:^0.0.4"
     },
     "typedoc": {

+ 3 - 1
packages/types/src/event.ts

@@ -9,11 +9,12 @@ export interface GlobalEventType {
 }
 export type TrackEventType = 'click' | 'menu';
 export interface TrackActionOption extends Dict<any> {
-    eventType: string;
+    event: string;
     maxWaitTime?: number;
 }
 
 export type EventReturnType = Promise<XMLHttpRequestResponseType>;
+export type EventReturnBooleanType = Promise<boolean>;
 export interface IBaseAction {
     trackView(url: string, referrer: string, uuid: string): EventReturnType;
     trackEvent(event_name: string, event_data: string, url?: string, uuid?: string): EventReturnType;
@@ -22,6 +23,7 @@ export interface IBaseAction {
 
 export interface ICustomAction {
     track(trackActionName: string, trackActionOption?: TrackActionOption): EventReturnType;
+    trackBeacon(trackActionName: string, trackActionOption?: TrackActionOption): EventReturnBooleanType;
     startTrack(trackActionName: string, trackActionOption?: TrackActionOption): EventReturnType;
     endTrack(trackActionName: string, trackActionOption?: TrackActionOption): EventReturnType;
 }

+ 2 - 1
packages/types/src/sdk.ts

@@ -17,7 +17,8 @@ export interface TrackEntityType {
     appId?: string;
     url?: string;
     referrer?: string;
-    eventType: string;
+    eventType?: string;
+    event: string;
     requestType?: string;
     TrackingType?: string;
     userId?: string;

+ 1 - 0
packages/utils/src/index.ts

@@ -1,3 +1,4 @@
 export { hook } from './hook';
 export { getGlobalObject } from './global';
 export { cloneDeep } from './cloneDeep';
+export { getNetworkType } from './network';

+ 56 - 0
packages/utils/src/network.ts

@@ -0,0 +1,56 @@
+export type Navigator = NavigatorNetworkInformation;
+export declare interface NavigatorNetworkInformation {
+    readonly connection?: NetworkInformation;
+}
+type Megabit = number;
+type Millisecond = number;
+export type EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g' | 'unknown';
+export type ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';
+
+export interface NetworkInformation extends EventTarget {
+    readonly type?: ConnectionType;
+    readonly effectiveType?: EffectiveConnectionType;
+    readonly downlinkMax?: Megabit;
+    readonly downlink?: Megabit;
+    readonly rtt?: Millisecond;
+    readonly saveData?: boolean;
+    onchange?: EventListener;
+}
+
+export function getNetworkType(): string {
+    /* wired 有线
+      bluetooth,
+      wifi,
+      2g,3g,4g,5g...,
+      unkown
+    */
+    const ua = navigator.userAgent;
+    const ut = (navigator as Navigator).connection as NetworkInformation;
+    let utt = ut ? (ut.type ? ut.type.toLowerCase() : ut.effectiveType.toLowerCase()) : null;
+    if (utt) {
+        switch (
+            utt //bluetooth,
+        ) {
+            case 'cellular':
+            case 'wimax':
+                utt = ut ? (ut.effectiveType ? ut.effectiveType.toLowerCase() : null) : null;
+                break;
+            case 'wifi':
+                break;
+            case 'ethernet':
+                utt = 'wired';
+                break;
+            case 'none':
+            case 'other':
+            case 'unknown':
+                utt = null;
+                break;
+            default:
+                break;
+        }
+    }
+    let networkStr = utt ? utt : ua.match(/NetType\/\w+/) ? ua.match(/NetType\/\w+/)[0] : 'unknown';
+    networkStr = networkStr.toLowerCase().replace('nettype/', '');
+
+    return networkStr ? (networkStr === '3gnet' ? '3g' : networkStr) : 'unknown';
+}

+ 1 - 1
packages/web/package.json

@@ -22,7 +22,7 @@
     "typescript": "~4.7.4"
   },
   "dependencies": {
-    "@medici/core": "workspace:^0.0.9"
+    "@medici/core": "workspace:^0.1.0"
   },
   "typedoc": {
     "entryPoint": "./src/index.ts",

+ 1 - 1
play/package.json

@@ -10,7 +10,7 @@
   },
   "dependencies": {
     "@highlightjs/vue-plugin": "^2.1.0",
-    "@medici/core": "workspace:^0.0.9",
+    "@medici/core": "workspace:^0.1.0",
     "@medici/web": "workspace:^0.0.6",
     "highlight.js": "^11.6.0",
     "vue": "^3.2.38",

+ 24 - 12
play/src/App.vue

@@ -2,20 +2,21 @@
 // This starter template is using Vue 3 <script setup> SFCs
 // Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
 import HelloWorld from './components/HelloWorld.vue';
-// import * as Medici from '@medici/web';
+import * as Medici from '@medici/web';
 
-// const medici = Medici.init({
-//     platform: 'web',
-//     appId: '7b5958d5-1ae6-4ad5-8a87-5fc8a4b92999',
-//     endPoint: '/track_api', //服务器
-//     stopTrack: false,
-//     config: {
-//         user: 'testUser',
-//         version: '1',
-//     },
-// });
+
+const medici = Medici.init({
+    platform: 'web',
+    appId: '7b5958d5-1ae6-4ad5-8a87-5fc8a4b92999',
+    endPoint: '/track_api', //服务器
+    stopTrack: false,
+    config: {
+        user: 'testUser',
+        version: '1',
+    },
+});
 // console.log('medici', medici);
-// (window as any).medici = medici;
+(window as any).medici = medici;
 
 // medici.track("BuyProduct", {
 //   eventType:"click",
@@ -23,6 +24,17 @@ import HelloWorld from './components/HelloWorld.vue';
 //   ProductPrice: 123.45,
 //   IsAddedToFav: false,
 // });
+
+const test = async () => {
+    const res = await medici.track('BuyProduct', {
+        event: 'what',
+        ProductName: 'MacBook Pro',
+        ProductPrice: 123.45,
+        IsAddedToFav: false,
+    });
+    console.log('res', res);
+};
+test();
 </script>
 
 <template>

+ 1 - 1
play/vite.config.ts

@@ -8,7 +8,7 @@ export default defineConfig({
         proxy: {
             // with options
             '/track_api': {
-                target: 'https://v4-test.4dkankan.com/',
+                target: 'https://test.4dkankan.com/',
                 changeOrigin: true,
                 rewrite: (path) => path.replace(/^\/track_api/, ''),
             },

文件差异内容过多而无法显示
+ 1135 - 892
pnpm-lock.yaml