@gctrack/uni 0.1.2 → 0.2.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.cjs CHANGED
@@ -1,5 +1,29 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- let _gctrack_protocol = require("@gctrack/protocol");
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ const __gctrack_core = __toESM(require("@gctrack/core"));
25
+ const __gctrack_protocol = __toESM(require("@gctrack/protocol"));
26
+
3
27
  //#region src/index.ts
4
28
  /** uni 适配实现 —— 全端用 uni.* 标准 API,不写 #ifdef */
5
29
  const uniAdapter = {
@@ -87,45 +111,140 @@ function detectPlatform() {
87
111
  const info = uni.getSystemInfoSync();
88
112
  const p = info.uniPlatform || info.platform;
89
113
  if (typeof p === "string") {
90
- if (p.includes("mp-weixin") || p.includes("weixin")) return _gctrack_protocol.Platform.WeixinMp;
91
- if (p.includes("mp-alipay") || p.includes("alipay")) return _gctrack_protocol.Platform.AlipayMp;
92
- if (p.includes("mp-jd") || p.includes("jd")) return _gctrack_protocol.Platform.JdMp;
93
- if (p.includes("mp-xhs") || p.includes("xhs")) return _gctrack_protocol.Platform.XhsMp;
94
- if (p.includes("mp-baidu") || p.includes("baidu")) return _gctrack_protocol.Platform.BaiduMp;
95
- if (p.includes("h5")) return _gctrack_protocol.Platform.H5;
114
+ if (p.includes("mp-weixin") || p.includes("weixin")) return __gctrack_protocol.Platform.WeixinMp;
115
+ if (p.includes("mp-alipay") || p.includes("alipay")) return __gctrack_protocol.Platform.AlipayMp;
116
+ if (p.includes("mp-jd") || p.includes("jd")) return __gctrack_protocol.Platform.JdMp;
117
+ if (p.includes("mp-xhs") || p.includes("xhs")) return __gctrack_protocol.Platform.XhsMp;
118
+ if (p.includes("mp-baidu") || p.includes("baidu")) return __gctrack_protocol.Platform.BaiduMp;
119
+ if (p.includes("h5")) return __gctrack_protocol.Platform.H5;
96
120
  }
97
121
  } catch (e) {}
98
- return _gctrack_protocol.Platform.WeixinMp;
122
+ return __gctrack_protocol.Platform.WeixinMp;
123
+ }
124
+ /**
125
+ * 兼容取组件名:Vue2 `vm.$options.name` / Vue3 `vm.type.name`。
126
+ */
127
+ function getComponentName(vm) {
128
+ if (!vm) return void 0;
129
+ const name = vm.$options && (vm.$options.name || vm.$options._componentTag) || vm.type && vm.type.name || vm.$ && vm.$.type && vm.$.type.name;
130
+ return name || void 0;
99
131
  }
100
132
  /**
101
- * 错误捕获一键挂载:
102
- * - Vue.config.errorHandler → vue_error
133
+ * 错误捕获一键挂载(Vue2/Vue3 通用):
134
+ * - appOrVue.config.errorHandler → vue_error
103
135
  * - uni.onUnhandledRejection → promise_error
104
- * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。
136
+ * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。
105
137
  */
106
- function installErrorCapture(Vue, tracker) {
107
- if (Vue && Vue.config) Vue.config.errorHandler = (err, vm, info) => {
108
- tracker.track(_gctrack_protocol.EventType.VueError, {
138
+ function installErrorCapture(appOrVue, tracker) {
139
+ if (appOrVue && appOrVue.config) appOrVue.config.errorHandler = (err, vm, info) => {
140
+ tracker.track(__gctrack_protocol.EventType.VueError, {
109
141
  message: err && err.message || String(err),
110
142
  stack: err ? err.stack : void 0,
111
143
  info,
112
- componentName: vm && vm.$options ? vm.$options.name || vm.$options._componentTag : void 0
144
+ componentName: getComponentName(vm)
113
145
  });
114
146
  };
115
147
  try {
116
148
  uni.onUnhandledRejection && uni.onUnhandledRejection((res) => {
117
149
  const reason = res ? res.reason : void 0;
118
- tracker.track(_gctrack_protocol.EventType.PromiseError, {
150
+ tracker.track(__gctrack_protocol.EventType.PromiseError, {
119
151
  message: reason && reason.message || String(reason),
120
152
  stack: reason ? reason.stack : void 0
121
153
  });
122
154
  });
123
155
  } catch (e) {}
124
156
  }
157
+ /**
158
+ * uni 端匿名访客 ID:走 uni storage(跨会话稳定),供 createTracker({ getVisitorId }) 注入。
159
+ */
160
+ function getUniVisitorId() {
161
+ let id = uniAdapter.getStorage(__gctrack_core.VISITOR_ID_KEY);
162
+ if (!id || typeof id !== "string") {
163
+ id = (0, __gctrack_core.generateId)();
164
+ uniAdapter.setStorage(__gctrack_core.VISITOR_ID_KEY, id);
165
+ }
166
+ return id;
167
+ }
168
+ /** 小程序持久化待发事件键(与 core Web 版同名) */
169
+ const MP_PENDING_KEY = "__gctrack_pending_events__";
170
+ /**
171
+ * 小程序离线持久化适配器:走 uniAdapter storage(uni.getStorageSync/setStorageSync),
172
+ * 供 createTracker({ persistence: 'mp', persistenceAdapter: createMpPersistence() }) 注入。
173
+ */
174
+ function createMpPersistence() {
175
+ return {
176
+ load() {
177
+ let events = [];
178
+ try {
179
+ const raw = uniAdapter.getStorage(MP_PENDING_KEY);
180
+ if (raw) {
181
+ events = typeof raw === "string" ? JSON.parse(raw) : raw;
182
+ uniAdapter.removeStorage(MP_PENDING_KEY);
183
+ }
184
+ } catch (e) {
185
+ events = [];
186
+ }
187
+ return Promise.resolve(events);
188
+ },
189
+ save(events) {
190
+ try {
191
+ uniAdapter.setStorage(MP_PENDING_KEY, JSON.stringify(events));
192
+ } catch (e) {}
193
+ return Promise.resolve();
194
+ },
195
+ clear() {
196
+ try {
197
+ uniAdapter.removeStorage(MP_PENDING_KEY);
198
+ } catch (e) {}
199
+ return Promise.resolve();
200
+ }
201
+ };
202
+ }
203
+ /**
204
+ * 小程序自动 PV:全局 mixin onShow,取 getCurrentPages() 栈顶 route+options 拼 pathname
205
+ * 上报 page_view,并显式写 event.pathname(小程序无 window.location,core autoCollect 取不到)。
206
+ */
207
+ function installPageView(appOrVue, tracker) {
208
+ appOrVue.mixin({ onShow() {
209
+ const info = uniAdapter.getPageInfo();
210
+ tracker.track(__gctrack_protocol.EventType.PageView, { route: info.url }, {
211
+ pathname: info.pathname,
212
+ url: info.url,
213
+ title: info.title
214
+ });
215
+ } });
216
+ }
217
+ /**
218
+ * GCTrack uni 插件对象(Vue2/Vue3 通用)。
219
+ * - 全局属性:V2 prototype / V3 globalProperties
220
+ * - 错误捕获:errorHandler(委托 installErrorCapture)
221
+ * - mixin:暴露 $track / $trackPageView
222
+ * - PV 采集:默认挂 installPageView(onShow)
223
+ */
224
+ const uniPlugin = { install(appOrVue, options) {
225
+ const { tracker, trackPageView = true } = options;
226
+ const v2 = typeof appOrVue === "function";
227
+ if (v2) appOrVue.prototype.$tracker = tracker;
228
+ else appOrVue.config.globalProperties.$tracker = tracker;
229
+ installErrorCapture(appOrVue, tracker);
230
+ appOrVue.mixin({ methods: {
231
+ $track(eventType, data) {
232
+ if (this.$tracker) this.$tracker.track(eventType, data);
233
+ },
234
+ $trackPageView(data) {
235
+ if (this.$tracker) this.$tracker.track(__gctrack_protocol.EventType.PageView, data);
236
+ }
237
+ } });
238
+ if (trackPageView) installPageView(appOrVue, tracker);
239
+ } };
240
+
125
241
  //#endregion
242
+ exports.createMpPersistence = createMpPersistence;
126
243
  exports.createUniSendFn = createUniSendFn;
127
244
  exports.detectPlatform = detectPlatform;
245
+ exports.getUniVisitorId = getUniVisitorId;
128
246
  exports.installErrorCapture = installErrorCapture;
247
+ exports.installPageView = installPageView;
129
248
  exports.uniAdapter = uniAdapter;
130
-
249
+ exports.uniPlugin = uniPlugin;
131
250
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["Platform","EventType"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @gctrack/uni —— 小程序多端适配\n *\n * 小程序无 window/document/navigator/sendBeacon/fetch/PerformanceObserver,\n * 本包提供 PlatformAdapter(存储/网络/生命周期/设备/页面)的 uni 实现,\n * 以及错误捕获(App.onError / unhandledRejection / Vue.errorHandler)一键挂载。\n *\n * 详见 design.md 5.5。完整实现(PV、点击、白屏耗时等)在「@gctrack/uni 完善」阶段补充。\n */\nimport type { Tracker } from '@gctrack/core'\nimport { EventType, Platform } from '@gctrack/protocol'\n\n// 小程序运行时注入的全局(各端一致提供 uni / getCurrentPages)\ndeclare const uni: any\ndeclare function getCurrentPages(): any[]\n\n/** 平台适配器接口 —— core 通过它解耦浏览器 API,详见 design.md 5.5 */\nexport interface PlatformAdapter {\n getStorage(key: string): any\n setStorage(key: string, value: any): void\n removeStorage(key: string): void\n request(opts: {\n url: string\n method?: string\n data?: any\n header?: Record<string, string>\n }): Promise<{ statusCode: number; data: any }>\n getSystemInfo(): Record<string, any>\n getPageInfo(): { pathname: string; url: string; title: string }\n onUnload(cb: () => void): void\n}\n\n/** uni 适配实现 —— 全端用 uni.* 标准 API,不写 #ifdef */\nexport const uniAdapter: PlatformAdapter = {\n getStorage: (k) => {\n try {\n return uni.getStorageSync(k)\n } catch (e) {\n return null\n }\n },\n setStorage: (k, v) => {\n try {\n uni.setStorageSync(k, v)\n } catch (e) {\n /* ignore */\n }\n },\n removeStorage: (k) => {\n try {\n uni.removeStorageSync(k)\n } catch (e) {\n /* ignore */\n }\n },\n request: (opts) =>\n new Promise((resolve, reject) => {\n uni.request({\n url: opts.url,\n method: (opts.method || 'POST') as any,\n data: opts.data,\n header: opts.header || {},\n success: (res: any) => resolve({ statusCode: res.statusCode, data: res.data }),\n fail: (err: any) => reject(err),\n })\n }),\n getSystemInfo: () => {\n try {\n return uni.getSystemInfoSync()\n } catch (e) {\n return {}\n }\n },\n getPageInfo: () => {\n try {\n const pages = getCurrentPages()\n const top = pages[pages.length - 1]\n const route: string = (top && top.route) || ''\n const options = (top && top.options) || {}\n const query = Object.keys(options)\n .map((k) => `${k}=${options[k]}`)\n .join('&')\n return {\n pathname: '/' + route,\n url: '/' + route + (query ? '?' + query : ''),\n title: '',\n }\n } catch (e) {\n return { pathname: '', url: '', title: '' }\n }\n },\n onUnload: (cb) => {\n // 兜底:App.onHide / Page.onHide 由 installAppLifecycle 接管,这里注册 uni 级监听\n try {\n uni.onAppHide && uni.onAppHide(cb)\n } catch (e) {\n /* ignore */\n }\n },\n}\n\n/**\n * 构造基于 uni.request 的 sendFn,供 createTracker({ sendFn }) 使用。\n * 小程序无 sendBeacon/fetch,统一走 uni.request;header 值强制 String()(XHS 要求)。\n */\nexport function createUniSendFn(reportUrl: string, appKey?: string) {\n return (events: any[]): Promise<void> =>\n uniAdapter\n .request({\n url: reportUrl,\n method: 'POST',\n data: events,\n header: {\n 'content-type': 'application/json',\n 'X-App-Key': appKey ? String(appKey) : '',\n },\n })\n .then(() => undefined)\n}\n\n/** 根据 uni 运行环境推断 Platform 标识(写入 context.platform) */\nexport function detectPlatform(): string {\n try {\n const info = uni.getSystemInfoSync()\n // uni-app 注入 UNI_PLATFORM / uniPlatform\n const p = info.uniPlatform || info.platform\n if (typeof p === 'string') {\n if (p.includes('mp-weixin') || p.includes('weixin')) return Platform.WeixinMp\n if (p.includes('mp-alipay') || p.includes('alipay')) return Platform.AlipayMp\n if (p.includes('mp-jd') || p.includes('jd')) return Platform.JdMp\n if (p.includes('mp-xhs') || p.includes('xhs')) return Platform.XhsMp\n if (p.includes('mp-baidu') || p.includes('baidu')) return Platform.BaiduMp\n if (p.includes('h5')) return Platform.H5\n }\n } catch (e) {\n /* ignore */\n }\n return Platform.WeixinMp\n}\n\n/**\n * 错误捕获一键挂载:\n * - Vue.config.errorHandler → vue_error\n * - uni.onUnhandledRejection → promise_error\n * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。\n */\nexport function installErrorCapture(Vue: any, tracker: Tracker): void {\n if (Vue && Vue.config) {\n Vue.config.errorHandler = (err: any, vm: any, info: string) => {\n tracker.track(EventType.VueError, {\n message: (err && err.message) || String(err),\n stack: err ? err.stack : undefined,\n info,\n componentName: vm && vm.$options ? (vm.$options.name || vm.$options._componentTag) : undefined,\n })\n }\n }\n try {\n uni.onUnhandledRejection &&\n uni.onUnhandledRejection((res: any) => {\n const reason = res ? res.reason : undefined\n tracker.track(EventType.PromiseError, {\n message: (reason && reason.message) || String(reason),\n stack: reason ? reason.stack : undefined,\n })\n })\n } catch (e) {\n /* ignore */\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["uniAdapter: PlatformAdapter","res: any","err: any","route: string","reportUrl: string","appKey?: string","events: any[]","Platform","vm: any","appOrVue: any","tracker: Tracker","info: string","EventType","VISITOR_ID_KEY","events: EventData[]","options: UniPluginOptions","eventType: string","data?: Record<string, any>"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @gctrack/uni —— 小程序多端适配\n *\n * 小程序无 window/document/navigator/sendBeacon/fetch/PerformanceObserver,\n * 本包提供 PlatformAdapter(存储/网络/生命周期/设备/页面)的 uni 实现,\n * 以及错误捕获(App.onError / unhandledRejection / Vue.errorHandler)一键挂载。\n *\n * 详见 design.md 5.5。完整实现(PV、点击、白屏耗时等)在「@gctrack/uni 完善」阶段补充。\n */\nimport type { Tracker } from '@gctrack/core'\nimport { generateId, VISITOR_ID_KEY } from '@gctrack/core'\nimport { EventType, Platform } from '@gctrack/protocol'\nimport type { EventData, PersistenceAdapter } from '@gctrack/protocol'\n\n// 小程序运行时注入的全局(各端一致提供 uni / getCurrentPages)\ndeclare const uni: any\ndeclare function getCurrentPages(): any[]\n\n/** 平台适配器接口 —— core 通过它解耦浏览器 API,详见 design.md 5.5 */\nexport interface PlatformAdapter {\n getStorage(key: string): any\n setStorage(key: string, value: any): void\n removeStorage(key: string): void\n request(opts: {\n url: string\n method?: string\n data?: any\n header?: Record<string, string>\n }): Promise<{ statusCode: number; data: any }>\n getSystemInfo(): Record<string, any>\n getPageInfo(): { pathname: string; url: string; title: string }\n onUnload(cb: () => void): void\n}\n\n/** uni 适配实现 —— 全端用 uni.* 标准 API,不写 #ifdef */\nexport const uniAdapter: PlatformAdapter = {\n getStorage: (k) => {\n try {\n return uni.getStorageSync(k)\n } catch (e) {\n return null\n }\n },\n setStorage: (k, v) => {\n try {\n uni.setStorageSync(k, v)\n } catch (e) {\n /* ignore */\n }\n },\n removeStorage: (k) => {\n try {\n uni.removeStorageSync(k)\n } catch (e) {\n /* ignore */\n }\n },\n request: (opts) =>\n new Promise((resolve, reject) => {\n uni.request({\n url: opts.url,\n method: (opts.method || 'POST') as any,\n data: opts.data,\n header: opts.header || {},\n success: (res: any) => resolve({ statusCode: res.statusCode, data: res.data }),\n fail: (err: any) => reject(err),\n })\n }),\n getSystemInfo: () => {\n try {\n return uni.getSystemInfoSync()\n } catch (e) {\n return {}\n }\n },\n getPageInfo: () => {\n try {\n const pages = getCurrentPages()\n const top = pages[pages.length - 1]\n const route: string = (top && top.route) || ''\n const options = (top && top.options) || {}\n const query = Object.keys(options)\n .map((k) => `${k}=${options[k]}`)\n .join('&')\n return {\n pathname: '/' + route,\n url: '/' + route + (query ? '?' + query : ''),\n title: '',\n }\n } catch (e) {\n return { pathname: '', url: '', title: '' }\n }\n },\n onUnload: (cb) => {\n // 兜底:App.onHide / Page.onHide 由 installAppLifecycle 接管,这里注册 uni 级监听\n try {\n uni.onAppHide && uni.onAppHide(cb)\n } catch (e) {\n /* ignore */\n }\n },\n}\n\n/**\n * 构造基于 uni.request 的 sendFn,供 createTracker({ sendFn }) 使用。\n * 小程序无 sendBeacon/fetch,统一走 uni.request;header 值强制 String()(XHS 要求)。\n */\nexport function createUniSendFn(reportUrl: string, appKey?: string) {\n return (events: any[]): Promise<void> =>\n uniAdapter\n .request({\n url: reportUrl,\n method: 'POST',\n data: events,\n header: {\n 'content-type': 'application/json',\n 'X-App-Key': appKey ? String(appKey) : '',\n },\n })\n .then(() => undefined)\n}\n\n/** 根据 uni 运行环境推断 Platform 标识(写入 context.platform) */\nexport function detectPlatform(): string {\n try {\n const info = uni.getSystemInfoSync()\n // uni-app 注入 UNI_PLATFORM / uniPlatform\n const p = info.uniPlatform || info.platform\n if (typeof p === 'string') {\n if (p.includes('mp-weixin') || p.includes('weixin')) return Platform.WeixinMp\n if (p.includes('mp-alipay') || p.includes('alipay')) return Platform.AlipayMp\n if (p.includes('mp-jd') || p.includes('jd')) return Platform.JdMp\n if (p.includes('mp-xhs') || p.includes('xhs')) return Platform.XhsMp\n if (p.includes('mp-baidu') || p.includes('baidu')) return Platform.BaiduMp\n if (p.includes('h5')) return Platform.H5\n }\n } catch (e) {\n /* ignore */\n }\n return Platform.WeixinMp\n}\n\n/**\n * 兼容取组件名:Vue2 `vm.$options.name` / Vue3 `vm.type.name`。\n */\nfunction getComponentName(vm: any): string | undefined {\n if (!vm) return undefined\n const name =\n (vm.$options && (vm.$options.name || vm.$options._componentTag)) ||\n (vm.type && vm.type.name) ||\n (vm.$ && vm.$.type && vm.$.type.name)\n return name || undefined\n}\n\n/**\n * 错误捕获一键挂载(Vue2/Vue3 通用):\n * - appOrVue.config.errorHandler → vue_error\n * - uni.onUnhandledRejection → promise_error\n * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。\n */\nexport function installErrorCapture(appOrVue: any, tracker: Tracker): void {\n if (appOrVue && appOrVue.config) {\n appOrVue.config.errorHandler = (err: any, vm: any, info: string) => {\n tracker.track(EventType.VueError, {\n message: (err && err.message) || String(err),\n stack: err ? err.stack : undefined,\n info,\n componentName: getComponentName(vm),\n })\n }\n }\n try {\n uni.onUnhandledRejection &&\n uni.onUnhandledRejection((res: any) => {\n const reason = res ? res.reason : undefined\n tracker.track(EventType.PromiseError, {\n message: (reason && reason.message) || String(reason),\n stack: reason ? reason.stack : undefined,\n })\n })\n } catch (e) {\n /* ignore */\n }\n}\n\n/**\n * uni 端匿名访客 ID:走 uni storage(跨会话稳定),供 createTracker({ getVisitorId }) 注入。\n */\nexport function getUniVisitorId(): string {\n let id = uniAdapter.getStorage(VISITOR_ID_KEY)\n if (!id || typeof id !== 'string') {\n id = generateId()\n uniAdapter.setStorage(VISITOR_ID_KEY, id)\n }\n return id\n}\n\n/** 小程序持久化待发事件键(与 core Web 版同名) */\nconst MP_PENDING_KEY = '__gctrack_pending_events__'\n\n/**\n * 小程序离线持久化适配器:走 uniAdapter storage(uni.getStorageSync/setStorageSync),\n * 供 createTracker({ persistence: 'mp', persistenceAdapter: createMpPersistence() }) 注入。\n */\nexport function createMpPersistence(): PersistenceAdapter {\n return {\n load(): Promise<EventData[]> {\n let events: EventData[] = []\n try {\n const raw = uniAdapter.getStorage(MP_PENDING_KEY)\n if (raw) {\n events = (typeof raw === 'string' ? JSON.parse(raw) : raw) as EventData[]\n uniAdapter.removeStorage(MP_PENDING_KEY)\n }\n } catch (e) {\n events = []\n }\n return Promise.resolve(events)\n },\n save(events: EventData[]): Promise<void> {\n try {\n uniAdapter.setStorage(MP_PENDING_KEY, JSON.stringify(events))\n } catch (e) {\n /* ignore */\n }\n return Promise.resolve()\n },\n clear(): Promise<void> {\n try {\n uniAdapter.removeStorage(MP_PENDING_KEY)\n } catch (e) {\n /* ignore */\n }\n return Promise.resolve()\n },\n }\n}\n\n/**\n * 小程序自动 PV:全局 mixin onShow,取 getCurrentPages() 栈顶 route+options 拼 pathname\n * 上报 page_view,并显式写 event.pathname(小程序无 window.location,core autoCollect 取不到)。\n */\nexport function installPageView(appOrVue: any, tracker: Tracker): void {\n appOrVue.mixin({\n onShow(this: any) {\n const info = uniAdapter.getPageInfo()\n tracker.track(\n EventType.PageView,\n { route: info.url },\n { pathname: info.pathname, url: info.url, title: info.title },\n )\n },\n })\n}\n\n/**\n * uni 插件选项\n */\nexport interface UniPluginOptions {\n tracker: Tracker\n /** 是否自动采集 PV(默认 true,挂全局 onShow mixin) */\n trackPageView?: boolean\n}\n\n/**\n * GCTrack uni 插件对象(Vue2/Vue3 通用)。\n * - 全局属性:V2 prototype / V3 globalProperties\n * - 错误捕获:errorHandler(委托 installErrorCapture)\n * - mixin:暴露 $track / $trackPageView\n * - PV 采集:默认挂 installPageView(onShow)\n */\nexport const uniPlugin = {\n install(appOrVue: any, options: UniPluginOptions): void {\n const { tracker, trackPageView = true } = options\n const v2 = typeof appOrVue === 'function'\n\n if (v2) {\n appOrVue.prototype.$tracker = tracker\n } else {\n appOrVue.config.globalProperties.$tracker = tracker\n }\n\n installErrorCapture(appOrVue, tracker)\n\n // Vue2/3 都有 .mixin\n appOrVue.mixin({\n methods: {\n $track(this: any, eventType: string, data?: Record<string, any>): void {\n if (this.$tracker) {\n this.$tracker.track(eventType, data)\n }\n },\n $trackPageView(this: any, data?: Record<string, any>): void {\n if (this.$tracker) {\n this.$tracker.track(EventType.PageView, data)\n }\n },\n },\n })\n\n if (trackPageView) {\n installPageView(appOrVue, tracker)\n }\n },\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Tracker } from "@gctrack/core";
2
+ import type { PersistenceAdapter } from "@gctrack/protocol";
2
3
  export interface PlatformAdapter {
3
4
  getStorage(key: string): any;
4
5
  setStorage(key: string, value: any): void;
@@ -23,4 +24,12 @@ export interface PlatformAdapter {
23
24
  export declare const uniAdapter: PlatformAdapter;
24
25
  export declare function createUniSendFn(reportUrl: string, appKey?: string): (events: any[]) => Promise<void>;
25
26
  export declare function detectPlatform(): string;
26
- export declare function installErrorCapture(Vue: any, tracker: Tracker): void;
27
+ export declare function installErrorCapture(appOrVue: any, tracker: Tracker): void;
28
+ export declare function getUniVisitorId(): string;
29
+ export declare function createMpPersistence(): PersistenceAdapter;
30
+ export declare function installPageView(appOrVue: any, tracker: Tracker): void;
31
+ export interface UniPluginOptions {
32
+ tracker: Tracker;
33
+ trackPageView?: boolean;
34
+ }
35
+ export declare const uniPlugin: {install(appOrVue: any, options: UniPluginOptions): void};
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Tracker } from "@gctrack/core";
2
+ import type { PersistenceAdapter } from "@gctrack/protocol";
2
3
  export interface PlatformAdapter {
3
4
  getStorage(key: string): any;
4
5
  setStorage(key: string, value: any): void;
@@ -23,4 +24,12 @@ export interface PlatformAdapter {
23
24
  export declare const uniAdapter: PlatformAdapter;
24
25
  export declare function createUniSendFn(reportUrl: string, appKey?: string): (events: any[]) => Promise<void>;
25
26
  export declare function detectPlatform(): string;
26
- export declare function installErrorCapture(Vue: any, tracker: Tracker): void;
27
+ export declare function installErrorCapture(appOrVue: any, tracker: Tracker): void;
28
+ export declare function getUniVisitorId(): string;
29
+ export declare function createMpPersistence(): PersistenceAdapter;
30
+ export declare function installPageView(appOrVue: any, tracker: Tracker): void;
31
+ export interface UniPluginOptions {
32
+ tracker: Tracker;
33
+ trackPageView?: boolean;
34
+ }
35
+ export declare const uniPlugin: {install(appOrVue: any, options: UniPluginOptions): void};
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
+ import { VISITOR_ID_KEY, generateId } from "@gctrack/core";
1
2
  import { EventType, Platform } from "@gctrack/protocol";
3
+
2
4
  //#region src/index.ts
3
5
  /** uni 适配实现 —— 全端用 uni.* 标准 API,不写 #ifdef */
4
6
  const uniAdapter = {
@@ -97,18 +99,26 @@ function detectPlatform() {
97
99
  return Platform.WeixinMp;
98
100
  }
99
101
  /**
100
- * 错误捕获一键挂载:
101
- * - Vue.config.errorHandler → vue_error
102
+ * 兼容取组件名:Vue2 `vm.$options.name` / Vue3 `vm.type.name`。
103
+ */
104
+ function getComponentName(vm) {
105
+ if (!vm) return void 0;
106
+ const name = vm.$options && (vm.$options.name || vm.$options._componentTag) || vm.type && vm.type.name || vm.$ && vm.$.type && vm.$.type.name;
107
+ return name || void 0;
108
+ }
109
+ /**
110
+ * 错误捕获一键挂载(Vue2/Vue3 通用):
111
+ * - appOrVue.config.errorHandler → vue_error
102
112
  * - uni.onUnhandledRejection → promise_error
103
- * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。
113
+ * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。
104
114
  */
105
- function installErrorCapture(Vue, tracker) {
106
- if (Vue && Vue.config) Vue.config.errorHandler = (err, vm, info) => {
115
+ function installErrorCapture(appOrVue, tracker) {
116
+ if (appOrVue && appOrVue.config) appOrVue.config.errorHandler = (err, vm, info) => {
107
117
  tracker.track(EventType.VueError, {
108
118
  message: err && err.message || String(err),
109
119
  stack: err ? err.stack : void 0,
110
120
  info,
111
- componentName: vm && vm.$options ? vm.$options.name || vm.$options._componentTag : void 0
121
+ componentName: getComponentName(vm)
112
122
  });
113
123
  };
114
124
  try {
@@ -121,7 +131,90 @@ function installErrorCapture(Vue, tracker) {
121
131
  });
122
132
  } catch (e) {}
123
133
  }
124
- //#endregion
125
- export { createUniSendFn, detectPlatform, installErrorCapture, uniAdapter };
134
+ /**
135
+ * uni 端匿名访客 ID:走 uni storage(跨会话稳定),供 createTracker({ getVisitorId }) 注入。
136
+ */
137
+ function getUniVisitorId() {
138
+ let id = uniAdapter.getStorage(VISITOR_ID_KEY);
139
+ if (!id || typeof id !== "string") {
140
+ id = generateId();
141
+ uniAdapter.setStorage(VISITOR_ID_KEY, id);
142
+ }
143
+ return id;
144
+ }
145
+ /** 小程序持久化待发事件键(与 core Web 版同名) */
146
+ const MP_PENDING_KEY = "__gctrack_pending_events__";
147
+ /**
148
+ * 小程序离线持久化适配器:走 uniAdapter storage(uni.getStorageSync/setStorageSync),
149
+ * 供 createTracker({ persistence: 'mp', persistenceAdapter: createMpPersistence() }) 注入。
150
+ */
151
+ function createMpPersistence() {
152
+ return {
153
+ load() {
154
+ let events = [];
155
+ try {
156
+ const raw = uniAdapter.getStorage(MP_PENDING_KEY);
157
+ if (raw) {
158
+ events = typeof raw === "string" ? JSON.parse(raw) : raw;
159
+ uniAdapter.removeStorage(MP_PENDING_KEY);
160
+ }
161
+ } catch (e) {
162
+ events = [];
163
+ }
164
+ return Promise.resolve(events);
165
+ },
166
+ save(events) {
167
+ try {
168
+ uniAdapter.setStorage(MP_PENDING_KEY, JSON.stringify(events));
169
+ } catch (e) {}
170
+ return Promise.resolve();
171
+ },
172
+ clear() {
173
+ try {
174
+ uniAdapter.removeStorage(MP_PENDING_KEY);
175
+ } catch (e) {}
176
+ return Promise.resolve();
177
+ }
178
+ };
179
+ }
180
+ /**
181
+ * 小程序自动 PV:全局 mixin onShow,取 getCurrentPages() 栈顶 route+options 拼 pathname
182
+ * 上报 page_view,并显式写 event.pathname(小程序无 window.location,core autoCollect 取不到)。
183
+ */
184
+ function installPageView(appOrVue, tracker) {
185
+ appOrVue.mixin({ onShow() {
186
+ const info = uniAdapter.getPageInfo();
187
+ tracker.track(EventType.PageView, { route: info.url }, {
188
+ pathname: info.pathname,
189
+ url: info.url,
190
+ title: info.title
191
+ });
192
+ } });
193
+ }
194
+ /**
195
+ * GCTrack uni 插件对象(Vue2/Vue3 通用)。
196
+ * - 全局属性:V2 prototype / V3 globalProperties
197
+ * - 错误捕获:errorHandler(委托 installErrorCapture)
198
+ * - mixin:暴露 $track / $trackPageView
199
+ * - PV 采集:默认挂 installPageView(onShow)
200
+ */
201
+ const uniPlugin = { install(appOrVue, options) {
202
+ const { tracker, trackPageView = true } = options;
203
+ const v2 = typeof appOrVue === "function";
204
+ if (v2) appOrVue.prototype.$tracker = tracker;
205
+ else appOrVue.config.globalProperties.$tracker = tracker;
206
+ installErrorCapture(appOrVue, tracker);
207
+ appOrVue.mixin({ methods: {
208
+ $track(eventType, data) {
209
+ if (this.$tracker) this.$tracker.track(eventType, data);
210
+ },
211
+ $trackPageView(data) {
212
+ if (this.$tracker) this.$tracker.track(EventType.PageView, data);
213
+ }
214
+ } });
215
+ if (trackPageView) installPageView(appOrVue, tracker);
216
+ } };
126
217
 
218
+ //#endregion
219
+ export { createMpPersistence, createUniSendFn, detectPlatform, getUniVisitorId, installErrorCapture, installPageView, uniAdapter, uniPlugin };
127
220
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @gctrack/uni —— 小程序多端适配\n *\n * 小程序无 window/document/navigator/sendBeacon/fetch/PerformanceObserver,\n * 本包提供 PlatformAdapter(存储/网络/生命周期/设备/页面)的 uni 实现,\n * 以及错误捕获(App.onError / unhandledRejection / Vue.errorHandler)一键挂载。\n *\n * 详见 design.md 5.5。完整实现(PV、点击、白屏耗时等)在「@gctrack/uni 完善」阶段补充。\n */\nimport type { Tracker } from '@gctrack/core'\nimport { EventType, Platform } from '@gctrack/protocol'\n\n// 小程序运行时注入的全局(各端一致提供 uni / getCurrentPages)\ndeclare const uni: any\ndeclare function getCurrentPages(): any[]\n\n/** 平台适配器接口 —— core 通过它解耦浏览器 API,详见 design.md 5.5 */\nexport interface PlatformAdapter {\n getStorage(key: string): any\n setStorage(key: string, value: any): void\n removeStorage(key: string): void\n request(opts: {\n url: string\n method?: string\n data?: any\n header?: Record<string, string>\n }): Promise<{ statusCode: number; data: any }>\n getSystemInfo(): Record<string, any>\n getPageInfo(): { pathname: string; url: string; title: string }\n onUnload(cb: () => void): void\n}\n\n/** uni 适配实现 —— 全端用 uni.* 标准 API,不写 #ifdef */\nexport const uniAdapter: PlatformAdapter = {\n getStorage: (k) => {\n try {\n return uni.getStorageSync(k)\n } catch (e) {\n return null\n }\n },\n setStorage: (k, v) => {\n try {\n uni.setStorageSync(k, v)\n } catch (e) {\n /* ignore */\n }\n },\n removeStorage: (k) => {\n try {\n uni.removeStorageSync(k)\n } catch (e) {\n /* ignore */\n }\n },\n request: (opts) =>\n new Promise((resolve, reject) => {\n uni.request({\n url: opts.url,\n method: (opts.method || 'POST') as any,\n data: opts.data,\n header: opts.header || {},\n success: (res: any) => resolve({ statusCode: res.statusCode, data: res.data }),\n fail: (err: any) => reject(err),\n })\n }),\n getSystemInfo: () => {\n try {\n return uni.getSystemInfoSync()\n } catch (e) {\n return {}\n }\n },\n getPageInfo: () => {\n try {\n const pages = getCurrentPages()\n const top = pages[pages.length - 1]\n const route: string = (top && top.route) || ''\n const options = (top && top.options) || {}\n const query = Object.keys(options)\n .map((k) => `${k}=${options[k]}`)\n .join('&')\n return {\n pathname: '/' + route,\n url: '/' + route + (query ? '?' + query : ''),\n title: '',\n }\n } catch (e) {\n return { pathname: '', url: '', title: '' }\n }\n },\n onUnload: (cb) => {\n // 兜底:App.onHide / Page.onHide 由 installAppLifecycle 接管,这里注册 uni 级监听\n try {\n uni.onAppHide && uni.onAppHide(cb)\n } catch (e) {\n /* ignore */\n }\n },\n}\n\n/**\n * 构造基于 uni.request 的 sendFn,供 createTracker({ sendFn }) 使用。\n * 小程序无 sendBeacon/fetch,统一走 uni.request;header 值强制 String()(XHS 要求)。\n */\nexport function createUniSendFn(reportUrl: string, appKey?: string) {\n return (events: any[]): Promise<void> =>\n uniAdapter\n .request({\n url: reportUrl,\n method: 'POST',\n data: events,\n header: {\n 'content-type': 'application/json',\n 'X-App-Key': appKey ? String(appKey) : '',\n },\n })\n .then(() => undefined)\n}\n\n/** 根据 uni 运行环境推断 Platform 标识(写入 context.platform) */\nexport function detectPlatform(): string {\n try {\n const info = uni.getSystemInfoSync()\n // uni-app 注入 UNI_PLATFORM / uniPlatform\n const p = info.uniPlatform || info.platform\n if (typeof p === 'string') {\n if (p.includes('mp-weixin') || p.includes('weixin')) return Platform.WeixinMp\n if (p.includes('mp-alipay') || p.includes('alipay')) return Platform.AlipayMp\n if (p.includes('mp-jd') || p.includes('jd')) return Platform.JdMp\n if (p.includes('mp-xhs') || p.includes('xhs')) return Platform.XhsMp\n if (p.includes('mp-baidu') || p.includes('baidu')) return Platform.BaiduMp\n if (p.includes('h5')) return Platform.H5\n }\n } catch (e) {\n /* ignore */\n }\n return Platform.WeixinMp\n}\n\n/**\n * 错误捕获一键挂载:\n * - Vue.config.errorHandler → vue_error\n * - uni.onUnhandledRejection → promise_error\n * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。\n */\nexport function installErrorCapture(Vue: any, tracker: Tracker): void {\n if (Vue && Vue.config) {\n Vue.config.errorHandler = (err: any, vm: any, info: string) => {\n tracker.track(EventType.VueError, {\n message: (err && err.message) || String(err),\n stack: err ? err.stack : undefined,\n info,\n componentName: vm && vm.$options ? (vm.$options.name || vm.$options._componentTag) : undefined,\n })\n }\n }\n try {\n uni.onUnhandledRejection &&\n uni.onUnhandledRejection((res: any) => {\n const reason = res ? res.reason : undefined\n tracker.track(EventType.PromiseError, {\n message: (reason && reason.message) || String(reason),\n stack: reason ? reason.stack : undefined,\n })\n })\n } catch (e) {\n /* ignore */\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["uniAdapter: PlatformAdapter","res: any","err: any","route: string","reportUrl: string","appKey?: string","events: any[]","vm: any","appOrVue: any","tracker: Tracker","info: string","events: EventData[]","options: UniPluginOptions","eventType: string","data?: Record<string, any>"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @gctrack/uni —— 小程序多端适配\n *\n * 小程序无 window/document/navigator/sendBeacon/fetch/PerformanceObserver,\n * 本包提供 PlatformAdapter(存储/网络/生命周期/设备/页面)的 uni 实现,\n * 以及错误捕获(App.onError / unhandledRejection / Vue.errorHandler)一键挂载。\n *\n * 详见 design.md 5.5。完整实现(PV、点击、白屏耗时等)在「@gctrack/uni 完善」阶段补充。\n */\nimport type { Tracker } from '@gctrack/core'\nimport { generateId, VISITOR_ID_KEY } from '@gctrack/core'\nimport { EventType, Platform } from '@gctrack/protocol'\nimport type { EventData, PersistenceAdapter } from '@gctrack/protocol'\n\n// 小程序运行时注入的全局(各端一致提供 uni / getCurrentPages)\ndeclare const uni: any\ndeclare function getCurrentPages(): any[]\n\n/** 平台适配器接口 —— core 通过它解耦浏览器 API,详见 design.md 5.5 */\nexport interface PlatformAdapter {\n getStorage(key: string): any\n setStorage(key: string, value: any): void\n removeStorage(key: string): void\n request(opts: {\n url: string\n method?: string\n data?: any\n header?: Record<string, string>\n }): Promise<{ statusCode: number; data: any }>\n getSystemInfo(): Record<string, any>\n getPageInfo(): { pathname: string; url: string; title: string }\n onUnload(cb: () => void): void\n}\n\n/** uni 适配实现 —— 全端用 uni.* 标准 API,不写 #ifdef */\nexport const uniAdapter: PlatformAdapter = {\n getStorage: (k) => {\n try {\n return uni.getStorageSync(k)\n } catch (e) {\n return null\n }\n },\n setStorage: (k, v) => {\n try {\n uni.setStorageSync(k, v)\n } catch (e) {\n /* ignore */\n }\n },\n removeStorage: (k) => {\n try {\n uni.removeStorageSync(k)\n } catch (e) {\n /* ignore */\n }\n },\n request: (opts) =>\n new Promise((resolve, reject) => {\n uni.request({\n url: opts.url,\n method: (opts.method || 'POST') as any,\n data: opts.data,\n header: opts.header || {},\n success: (res: any) => resolve({ statusCode: res.statusCode, data: res.data }),\n fail: (err: any) => reject(err),\n })\n }),\n getSystemInfo: () => {\n try {\n return uni.getSystemInfoSync()\n } catch (e) {\n return {}\n }\n },\n getPageInfo: () => {\n try {\n const pages = getCurrentPages()\n const top = pages[pages.length - 1]\n const route: string = (top && top.route) || ''\n const options = (top && top.options) || {}\n const query = Object.keys(options)\n .map((k) => `${k}=${options[k]}`)\n .join('&')\n return {\n pathname: '/' + route,\n url: '/' + route + (query ? '?' + query : ''),\n title: '',\n }\n } catch (e) {\n return { pathname: '', url: '', title: '' }\n }\n },\n onUnload: (cb) => {\n // 兜底:App.onHide / Page.onHide 由 installAppLifecycle 接管,这里注册 uni 级监听\n try {\n uni.onAppHide && uni.onAppHide(cb)\n } catch (e) {\n /* ignore */\n }\n },\n}\n\n/**\n * 构造基于 uni.request 的 sendFn,供 createTracker({ sendFn }) 使用。\n * 小程序无 sendBeacon/fetch,统一走 uni.request;header 值强制 String()(XHS 要求)。\n */\nexport function createUniSendFn(reportUrl: string, appKey?: string) {\n return (events: any[]): Promise<void> =>\n uniAdapter\n .request({\n url: reportUrl,\n method: 'POST',\n data: events,\n header: {\n 'content-type': 'application/json',\n 'X-App-Key': appKey ? String(appKey) : '',\n },\n })\n .then(() => undefined)\n}\n\n/** 根据 uni 运行环境推断 Platform 标识(写入 context.platform) */\nexport function detectPlatform(): string {\n try {\n const info = uni.getSystemInfoSync()\n // uni-app 注入 UNI_PLATFORM / uniPlatform\n const p = info.uniPlatform || info.platform\n if (typeof p === 'string') {\n if (p.includes('mp-weixin') || p.includes('weixin')) return Platform.WeixinMp\n if (p.includes('mp-alipay') || p.includes('alipay')) return Platform.AlipayMp\n if (p.includes('mp-jd') || p.includes('jd')) return Platform.JdMp\n if (p.includes('mp-xhs') || p.includes('xhs')) return Platform.XhsMp\n if (p.includes('mp-baidu') || p.includes('baidu')) return Platform.BaiduMp\n if (p.includes('h5')) return Platform.H5\n }\n } catch (e) {\n /* ignore */\n }\n return Platform.WeixinMp\n}\n\n/**\n * 兼容取组件名:Vue2 `vm.$options.name` / Vue3 `vm.type.name`。\n */\nfunction getComponentName(vm: any): string | undefined {\n if (!vm) return undefined\n const name =\n (vm.$options && (vm.$options.name || vm.$options._componentTag)) ||\n (vm.type && vm.type.name) ||\n (vm.$ && vm.$.type && vm.$.type.name)\n return name || undefined\n}\n\n/**\n * 错误捕获一键挂载(Vue2/Vue3 通用):\n * - appOrVue.config.errorHandler → vue_error\n * - uni.onUnhandledRejection → promise_error\n * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。\n */\nexport function installErrorCapture(appOrVue: any, tracker: Tracker): void {\n if (appOrVue && appOrVue.config) {\n appOrVue.config.errorHandler = (err: any, vm: any, info: string) => {\n tracker.track(EventType.VueError, {\n message: (err && err.message) || String(err),\n stack: err ? err.stack : undefined,\n info,\n componentName: getComponentName(vm),\n })\n }\n }\n try {\n uni.onUnhandledRejection &&\n uni.onUnhandledRejection((res: any) => {\n const reason = res ? res.reason : undefined\n tracker.track(EventType.PromiseError, {\n message: (reason && reason.message) || String(reason),\n stack: reason ? reason.stack : undefined,\n })\n })\n } catch (e) {\n /* ignore */\n }\n}\n\n/**\n * uni 端匿名访客 ID:走 uni storage(跨会话稳定),供 createTracker({ getVisitorId }) 注入。\n */\nexport function getUniVisitorId(): string {\n let id = uniAdapter.getStorage(VISITOR_ID_KEY)\n if (!id || typeof id !== 'string') {\n id = generateId()\n uniAdapter.setStorage(VISITOR_ID_KEY, id)\n }\n return id\n}\n\n/** 小程序持久化待发事件键(与 core Web 版同名) */\nconst MP_PENDING_KEY = '__gctrack_pending_events__'\n\n/**\n * 小程序离线持久化适配器:走 uniAdapter storage(uni.getStorageSync/setStorageSync),\n * 供 createTracker({ persistence: 'mp', persistenceAdapter: createMpPersistence() }) 注入。\n */\nexport function createMpPersistence(): PersistenceAdapter {\n return {\n load(): Promise<EventData[]> {\n let events: EventData[] = []\n try {\n const raw = uniAdapter.getStorage(MP_PENDING_KEY)\n if (raw) {\n events = (typeof raw === 'string' ? JSON.parse(raw) : raw) as EventData[]\n uniAdapter.removeStorage(MP_PENDING_KEY)\n }\n } catch (e) {\n events = []\n }\n return Promise.resolve(events)\n },\n save(events: EventData[]): Promise<void> {\n try {\n uniAdapter.setStorage(MP_PENDING_KEY, JSON.stringify(events))\n } catch (e) {\n /* ignore */\n }\n return Promise.resolve()\n },\n clear(): Promise<void> {\n try {\n uniAdapter.removeStorage(MP_PENDING_KEY)\n } catch (e) {\n /* ignore */\n }\n return Promise.resolve()\n },\n }\n}\n\n/**\n * 小程序自动 PV:全局 mixin onShow,取 getCurrentPages() 栈顶 route+options 拼 pathname\n * 上报 page_view,并显式写 event.pathname(小程序无 window.location,core autoCollect 取不到)。\n */\nexport function installPageView(appOrVue: any, tracker: Tracker): void {\n appOrVue.mixin({\n onShow(this: any) {\n const info = uniAdapter.getPageInfo()\n tracker.track(\n EventType.PageView,\n { route: info.url },\n { pathname: info.pathname, url: info.url, title: info.title },\n )\n },\n })\n}\n\n/**\n * uni 插件选项\n */\nexport interface UniPluginOptions {\n tracker: Tracker\n /** 是否自动采集 PV(默认 true,挂全局 onShow mixin) */\n trackPageView?: boolean\n}\n\n/**\n * GCTrack uni 插件对象(Vue2/Vue3 通用)。\n * - 全局属性:V2 prototype / V3 globalProperties\n * - 错误捕获:errorHandler(委托 installErrorCapture)\n * - mixin:暴露 $track / $trackPageView\n * - PV 采集:默认挂 installPageView(onShow)\n */\nexport const uniPlugin = {\n install(appOrVue: any, options: UniPluginOptions): void {\n const { tracker, trackPageView = true } = options\n const v2 = typeof appOrVue === 'function'\n\n if (v2) {\n appOrVue.prototype.$tracker = tracker\n } else {\n appOrVue.config.globalProperties.$tracker = tracker\n }\n\n installErrorCapture(appOrVue, tracker)\n\n // Vue2/3 都有 .mixin\n appOrVue.mixin({\n methods: {\n $track(this: any, eventType: string, data?: Record<string, any>): void {\n if (this.$tracker) {\n this.$tracker.track(eventType, data)\n }\n },\n $trackPageView(this: any, data?: Record<string, any>): void {\n if (this.$tracker) {\n this.$tracker.track(EventType.PageView, data)\n }\n },\n },\n })\n\n if (trackPageView) {\n installPageView(appOrVue, tracker)\n }\n },\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gctrack/uni",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "GCTrack 小程序多端适配 —— uni-app 微信/支付宝/京东/小红书/H5",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -32,13 +32,18 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@gctrack/protocol": "0.1.2"
35
+ "@gctrack/protocol": "0.2.0"
36
36
  },
37
37
  "peerDependencies": {
38
- "@gctrack/core": "0.1.2"
38
+ "@gctrack/core": "0.2.0"
39
+ },
40
+ "devDependencies": {
41
+ "happy-dom": "^15.0.0",
42
+ "vitest": "^2.0.0"
39
43
  },
40
44
  "scripts": {
41
45
  "build": "tsdown",
42
- "dev": "tsdown --watch"
46
+ "dev": "tsdown --watch",
47
+ "test": "vitest run"
43
48
  }
44
49
  }