@gctrack/uni 0.1.0 → 0.1.1

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
@@ -44,8 +44,8 @@ const uniAdapter = {
44
44
  try {
45
45
  const pages = getCurrentPages();
46
46
  const top = pages[pages.length - 1];
47
- const route = top?.route || "";
48
- const options = top?.options || {};
47
+ const route = top && top.route || "";
48
+ const options = top && top.options || {};
49
49
  const query = Object.keys(options).map((k) => `${k}=${options[k]}`).join("&");
50
50
  return {
51
51
  pathname: "/" + route,
@@ -104,20 +104,20 @@ function detectPlatform() {
104
104
  * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。
105
105
  */
106
106
  function installErrorCapture(Vue, tracker) {
107
- if (Vue?.config) Vue.config.errorHandler = (err, vm, info) => {
107
+ if (Vue && Vue.config) Vue.config.errorHandler = (err, vm, info) => {
108
108
  tracker.track(_gctrack_protocol.EventType.VueError, {
109
- message: err?.message || String(err),
110
- stack: err?.stack,
109
+ message: err && err.message || String(err),
110
+ stack: err ? err.stack : void 0,
111
111
  info,
112
- componentName: vm?.$options?.name || vm?.$options?._componentTag
112
+ componentName: vm && vm.$options ? vm.$options.name || vm.$options._componentTag : void 0
113
113
  });
114
114
  };
115
115
  try {
116
116
  uni.onUnhandledRejection && uni.onUnhandledRejection((res) => {
117
- const reason = res?.reason;
117
+ const reason = res ? res.reason : void 0;
118
118
  tracker.track(_gctrack_protocol.EventType.PromiseError, {
119
- message: reason?.message || String(reason),
120
- stack: reason?.stack
119
+ message: reason && reason.message || String(reason),
120
+ stack: reason ? reason.stack : void 0
121
121
  });
122
122
  });
123
123
  } catch {}
@@ -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 {\n return null\n }\n },\n setStorage: (k, v) => {\n try {\n uni.setStorageSync(k, v)\n } catch {\n /* ignore */\n }\n },\n removeStorage: (k) => {\n try {\n uni.removeStorageSync(k)\n } catch {\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 {\n return {}\n }\n },\n getPageInfo: () => {\n try {\n const pages = getCurrentPages()\n const top = pages[pages.length - 1]\n const route: string = top?.route || ''\n const options = 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 {\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 {\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 {\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?.config) {\n Vue.config.errorHandler = (err: any, vm: any, info: string) => {\n tracker.track(EventType.VueError, {\n message: err?.message || String(err),\n stack: err?.stack,\n info,\n componentName: vm?.$options?.name || vm?.$options?._componentTag,\n })\n }\n }\n try {\n uni.onUnhandledRejection &&\n uni.onUnhandledRejection((res: any) => {\n const reason = res?.reason\n tracker.track(EventType.PromiseError, {\n message: reason?.message || String(reason),\n stack: reason?.stack,\n })\n })\n } catch {\n /* ignore */\n }\n}\n"],"mappings":"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"}
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 {\n return null\n }\n },\n setStorage: (k, v) => {\n try {\n uni.setStorageSync(k, v)\n } catch {\n /* ignore */\n }\n },\n removeStorage: (k) => {\n try {\n uni.removeStorageSync(k)\n } catch {\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 {\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 {\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 {\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 {\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 {\n /* ignore */\n }\n}\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -44,8 +44,8 @@ const uniAdapter = {
44
44
  try {
45
45
  const pages = getCurrentPages();
46
46
  const top = pages[pages.length - 1];
47
- const route = top?.route || "";
48
- const options = top?.options || {};
47
+ const route = top && top.route || "";
48
+ const options = top && top.options || {};
49
49
  const query = Object.keys(options).map((k) => `${k}=${options[k]}`).join("&");
50
50
  return {
51
51
  pathname: "/" + route,
@@ -104,20 +104,20 @@ function detectPlatform() {
104
104
  * App.onError 需在 App.vue 里手动调用 tracker.track(见 design.md 13.2)。
105
105
  */
106
106
  function installErrorCapture(Vue, tracker) {
107
- if (Vue?.config) Vue.config.errorHandler = (err, vm, info) => {
107
+ if (Vue && Vue.config) Vue.config.errorHandler = (err, vm, info) => {
108
108
  tracker.track(EventType.VueError, {
109
- message: err?.message || String(err),
110
- stack: err?.stack,
109
+ message: err && err.message || String(err),
110
+ stack: err ? err.stack : void 0,
111
111
  info,
112
- componentName: vm?.$options?.name || vm?.$options?._componentTag
112
+ componentName: vm && vm.$options ? vm.$options.name || vm.$options._componentTag : void 0
113
113
  });
114
114
  };
115
115
  try {
116
116
  uni.onUnhandledRejection && uni.onUnhandledRejection((res) => {
117
- const reason = res?.reason;
117
+ const reason = res ? res.reason : void 0;
118
118
  tracker.track(EventType.PromiseError, {
119
- message: reason?.message || String(reason),
120
- stack: reason?.stack
119
+ message: reason && reason.message || String(reason),
120
+ stack: reason ? reason.stack : void 0
121
121
  });
122
122
  });
123
123
  } catch {}
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 {\n return null\n }\n },\n setStorage: (k, v) => {\n try {\n uni.setStorageSync(k, v)\n } catch {\n /* ignore */\n }\n },\n removeStorage: (k) => {\n try {\n uni.removeStorageSync(k)\n } catch {\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 {\n return {}\n }\n },\n getPageInfo: () => {\n try {\n const pages = getCurrentPages()\n const top = pages[pages.length - 1]\n const route: string = top?.route || ''\n const options = 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 {\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 {\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 {\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?.config) {\n Vue.config.errorHandler = (err: any, vm: any, info: string) => {\n tracker.track(EventType.VueError, {\n message: err?.message || String(err),\n stack: err?.stack,\n info,\n componentName: vm?.$options?.name || vm?.$options?._componentTag,\n })\n }\n }\n try {\n uni.onUnhandledRejection &&\n uni.onUnhandledRejection((res: any) => {\n const reason = res?.reason\n tracker.track(EventType.PromiseError, {\n message: reason?.message || String(reason),\n stack: reason?.stack,\n })\n })\n } catch {\n /* ignore */\n }\n}\n"],"mappings":";;;;AAiCA,MAAa,aAA8B;CACzC,aAAa,MAAM;EACjB,IAAI;GACF,OAAO,IAAI,eAAe,EAAE;UACtB;GACN,OAAO;;;CAGX,aAAa,GAAG,MAAM;EACpB,IAAI;GACF,IAAI,eAAe,GAAG,EAAE;UAClB;;CAIV,gBAAgB,MAAM;EACpB,IAAI;GACF,IAAI,kBAAkB,EAAE;UAClB;;CAIV,UAAU,SACR,IAAI,SAAS,SAAS,WAAW;EAC/B,IAAI,QAAQ;GACV,KAAK,KAAK;GACV,QAAS,KAAK,UAAU;GACxB,MAAM,KAAK;GACX,QAAQ,KAAK,UAAU,EAAE;GACzB,UAAU,QAAa,QAAQ;IAAE,YAAY,IAAI;IAAY,MAAM,IAAI;IAAM,CAAC;GAC9E,OAAO,QAAa,OAAO,IAAI;GAChC,CAAC;GACF;CACJ,qBAAqB;EACnB,IAAI;GACF,OAAO,IAAI,mBAAmB;UACxB;GACN,OAAO,EAAE;;;CAGb,mBAAmB;EACjB,IAAI;GACF,MAAM,QAAQ,iBAAiB;GAC/B,MAAM,MAAM,MAAM,MAAM,SAAS;GACjC,MAAM,QAAgB,KAAK,SAAS;GACpC,MAAM,UAAU,KAAK,WAAW,EAAE;GAClC,MAAM,QAAQ,OAAO,KAAK,QAAQ,CAC/B,KAAK,MAAM,GAAG,EAAE,GAAG,QAAQ,KAAK,CAChC,KAAK,IAAI;GACZ,OAAO;IACL,UAAU,MAAM;IAChB,KAAK,MAAM,SAAS,QAAQ,MAAM,QAAQ;IAC1C,OAAO;IACR;UACK;GACN,OAAO;IAAE,UAAU;IAAI,KAAK;IAAI,OAAO;IAAI;;;CAG/C,WAAW,OAAO;EAEhB,IAAI;GACF,IAAI,aAAa,IAAI,UAAU,GAAG;UAC5B;;CAIX;;;;;AAMD,SAAgB,gBAAgB,WAAmB,QAAiB;CAClE,QAAQ,WACN,WACG,QAAQ;EACP,KAAK;EACL,QAAQ;EACR,MAAM;EACN,QAAQ;GACN,gBAAgB;GAChB,aAAa,SAAS,OAAO,OAAO,GAAG;GACxC;EACF,CAAC,CACD,WAAW,KAAA,EAAU;;;AAI5B,SAAgB,iBAAyB;CACvC,IAAI;EACF,MAAM,OAAO,IAAI,mBAAmB;EAEpC,MAAM,IAAI,KAAK,eAAe,KAAK;EACnC,IAAI,OAAO,MAAM,UAAU;GACzB,IAAI,EAAE,SAAS,YAAY,IAAI,EAAE,SAAS,SAAS,EAAE,OAAO,SAAS;GACrE,IAAI,EAAE,SAAS,YAAY,IAAI,EAAE,SAAS,SAAS,EAAE,OAAO,SAAS;GACrE,IAAI,EAAE,SAAS,QAAQ,IAAI,EAAE,SAAS,KAAK,EAAE,OAAO,SAAS;GAC7D,IAAI,EAAE,SAAS,SAAS,IAAI,EAAE,SAAS,MAAM,EAAE,OAAO,SAAS;GAC/D,IAAI,EAAE,SAAS,WAAW,IAAI,EAAE,SAAS,QAAQ,EAAE,OAAO,SAAS;GACnE,IAAI,EAAE,SAAS,KAAK,EAAE,OAAO,SAAS;;SAElC;CAGR,OAAO,SAAS;;;;;;;;AASlB,SAAgB,oBAAoB,KAAU,SAAwB;CACpE,IAAI,KAAK,QACP,IAAI,OAAO,gBAAgB,KAAU,IAAS,SAAiB;EAC7D,QAAQ,MAAM,UAAU,UAAU;GAChC,SAAS,KAAK,WAAW,OAAO,IAAI;GACpC,OAAO,KAAK;GACZ;GACA,eAAe,IAAI,UAAU,QAAQ,IAAI,UAAU;GACpD,CAAC;;CAGN,IAAI;EACF,IAAI,wBACF,IAAI,sBAAsB,QAAa;GACrC,MAAM,SAAS,KAAK;GACpB,QAAQ,MAAM,UAAU,cAAc;IACpC,SAAS,QAAQ,WAAW,OAAO,OAAO;IAC1C,OAAO,QAAQ;IAChB,CAAC;IACF;SACE"}
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 {\n return null\n }\n },\n setStorage: (k, v) => {\n try {\n uni.setStorageSync(k, v)\n } catch {\n /* ignore */\n }\n },\n removeStorage: (k) => {\n try {\n uni.removeStorageSync(k)\n } catch {\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 {\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 {\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 {\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 {\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 {\n /* ignore */\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.0",
3
+ "version": "0.1.1",
4
4
  "description": "GCTrack 小程序多端适配 —— uni-app 微信/支付宝/京东/小红书/H5",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -32,10 +32,10 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@gctrack/protocol": "0.1.0"
35
+ "@gctrack/protocol": "0.1.1"
36
36
  },
37
37
  "peerDependencies": {
38
- "@gctrack/core": "0.1.0"
38
+ "@gctrack/core": "0.1.1"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsdown",