@yuanze_dev/tracker-miniprogram 0.7.0 → 0.8.2

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.js CHANGED
@@ -1 +1 @@
1
- "use strict";var __defProp=Object.defineProperty;var __defProps=Object.defineProperties;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropDescs=Object.getOwnPropertyDescriptors;var __getOwnPropNames=Object.getOwnPropertyNames;var __getOwnPropSymbols=Object.getOwnPropertySymbols;var __hasOwnProp=Object.prototype.hasOwnProperty;var __propIsEnum=Object.prototype.propertyIsEnumerable;var __pow=Math.pow;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __spreadValues=(a,b)=>{for(var prop in b||(b={}))if(__hasOwnProp.call(b,prop))__defNormalProp(a,prop,b[prop]);if(__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(b)){if(__propIsEnum.call(b,prop))__defNormalProp(a,prop,b[prop])}return a};var __spreadProps=(a,b)=>__defProps(a,__getOwnPropDescs(b));var __objRest=(source,exclude)=>{var target={};for(var prop in source)if(__hasOwnProp.call(source,prop)&&exclude.indexOf(prop)<0)target[prop]=source[prop];if(source!=null&&__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(source)){if(exclude.indexOf(prop)<0&&__propIsEnum.call(source,prop))target[prop]=source[prop]}return target};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);var __async=(__this,__arguments,generator)=>{return new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}};var rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}};var step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())})};var index_exports={};__export(index_exports,{SYSTEM_EVENTS:()=>SYSTEM_EVENTS,default:()=>index_default,enableAutoTrack:()=>enableAutoTrack,flush:()=>flush,getTracker:()=>getTracker,identify:()=>identify,init:()=>init,isSystemEvent:()=>isSystemEvent,register:()=>register,reset:()=>reset,track:()=>track,trackTap:()=>trackTap,tracker:()=>tracker,wxEnvContext:()=>wxEnvContext,wxPersistence:()=>wxPersistence,wxSender:()=>wxSender,wxStorage:()=>wxStorage});module.exports=__toCommonJS(index_exports);function uuid(){const c=globalThis.crypto;if(typeof(c==null?void 0:c.randomUUID)==="function"){try{return c.randomUUID()}catch(e){}}if(typeof(c==null?void 0:c.getRandomValues)==="function"){try{const b2=c.getRandomValues(new Uint8Array(16));return formatUuid(b2)}catch(e){}}const b=new Uint8Array(16);for(let i=0;i<16;i+=1)b[i]=Math.floor(Math.random()*256);return formatUuid(b)}function formatUuid(b){b[6]=b[6]&15|64;b[8]=b[8]&63|128;const hex=[];for(let i=0;i<16;i+=1)hex.push(b[i].toString(16).padStart(2,"0"));const s=hex.join("");return`${s.slice(0,8)}-${s.slice(8,12)}-${s.slice(12,16)}-${s.slice(16,20)}-${s.slice(20)}`}function memoryStorage(){const m=new Map;return{get:k=>{var _a;return(_a=m.get(k))!=null?_a:null},set:(k,v)=>void m.set(k,v),remove:k=>void m.delete(k)}}function webStorage(){const mem=memoryStorage();let ls=null;try{ls=typeof localStorage!=="undefined"?localStorage:null}catch(e){ls=null}if(!ls)return mem;return{get(k){try{return ls.getItem(k)}catch(e){return mem.get(k)}},set(k,v){try{ls.setItem(k,v)}catch(e){mem.set(k,v)}},remove(k){try{ls.removeItem(k)}catch(e){mem.remove(k)}}}}var STORAGE_KEYS={anonymousId:"yz_anon",userId:"yz_uid",session:"yz_session"};var SESSION_TIMEOUT_MS=30*60*1e3;var TOUCH_PERSIST_MS=60*1e3;function dayKey(ts){const d=new Date(ts);const p=n=>String(n).padStart(2,"0");return`${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}`}var Identity=class{constructor(store,now=Date.now){__publicField(this,"store",store);__publicField(this,"now",now);__publicField(this,"anonymousId");__publicField(this,"userId");__publicField(this,"session");__publicField(this,"persistedAt");var _a;this.anonymousId=(_a=this.store.get(STORAGE_KEYS.anonymousId))!=null?_a:this.newAnonymousId();this.userId=this.store.get(STORAGE_KEYS.userId)||null;this.session=this.loadSession();this.persistedAt=this.session.lastActive}newAnonymousId(){const id=`anon_${uuid()}`;this.store.set(STORAGE_KEYS.anonymousId,id);return id}loadSession(){const raw=this.store.get(STORAGE_KEYS.session);if(raw){try{const s=JSON.parse(raw);if((s==null?void 0:s.id)&&typeof s.lastActive==="number"&&!this.expired(s,this.now()))return s}catch(e){}}return this.startSession(this.now())}expired(s,at){return at-s.lastActive>SESSION_TIMEOUT_MS||s.day!==dayKey(at)}startSession(at){const s={id:uuid(),lastActive:at,day:dayKey(at)};this.store.set(STORAGE_KEYS.session,JSON.stringify(s));this.persistedAt=at;return s}touch(){const at=this.now();if(this.expired(this.session,at)){this.session=this.startSession(at);return}this.session.lastActive=at;if(at-this.persistedAt>=TOUCH_PERSIST_MS){this.store.set(STORAGE_KEYS.session,JSON.stringify(this.session));this.persistedAt=at}}identify(userId){const id=String(userId!=null?userId:"").trim();if(!id||id===this.userId)return false;this.userId=id;this.store.set(STORAGE_KEYS.userId,id);return true}reset(){this.userId=null;this.store.remove(STORAGE_KEYS.userId);this.anonymousId=this.newAnonymousId();this.session=this.startSession(this.now())}snapshot(){var _a;return{distinctId:(_a=this.userId)!=null?_a:this.anonymousId,anonymousId:this.anonymousId,userId:this.userId,sessionId:this.session.id}}setAnonymousId(id){this.anonymousId=id;this.store.set(STORAGE_KEYS.anonymousId,id)}};var DB_NAME="yz_tracker";var STORE="queue";var DEFAULT_LIMIT=500;function openDb(dbName){return new Promise((resolve,reject)=>{const req=indexedDB.open(dbName,1);req.onupgradeneeded=()=>{const db=req.result;if(!db.objectStoreNames.contains(STORE)){db.createObjectStore(STORE,{keyPath:"eventId"}).createIndex("savedAt","savedAt")}};req.onsuccess=()=>resolve(req.result);req.onerror=()=>reject(req.error);req.onblocked=()=>reject(new Error("indexedDB blocked"))})}function indexedDbPersistence(opts={}){var _a,_b;if(typeof indexedDB==="undefined")return null;const dbName=(_a=opts.dbName)!=null?_a:DB_NAME;const limit=(_b=opts.limit)!=null?_b:DEFAULT_LIMIT;let dbPromise=null;const db=()=>{dbPromise!=null?dbPromise:dbPromise=openDb(dbName);return dbPromise};const write=fn=>__async(null,null,function*(){try{const d=yield db();const tx=d.transaction(STORE,"readwrite");fn(tx.objectStore(STORE))}catch(e){}});return{load(){return __async(this,null,function*(){try{const d=yield db();const tx=d.transaction(STORE,"readonly");const req=tx.objectStore(STORE).index("savedAt").getAll();const rows=yield new Promise((resolve,reject)=>{req.onsuccess=()=>resolve(req.result);req.onerror=()=>reject(req.error)});return rows.map(r=>r.payload)}catch(e){return[]}})},add(records){void write(store=>{for(const r of records)store.put(r);const countReq=store.count();countReq.onsuccess=()=>{const over=countReq.result-limit;if(over<=0)return;let dropped=0;const cur=store.index("savedAt").openCursor();cur.onsuccess=()=>{const c=cur.result;if(!c||dropped>=over)return;c.delete();dropped+=1;c.continue()}}})},remove(eventIds){if(!eventIds.length)return;void write(store=>{for(const id of eventIds)store.delete(id)})}}}var SDK_NAME="@yuanze_dev/tracker";var SDK_VERSION="0.7.0";var PROTOCOL_VERSION=1;var MAX_BATCH_SIZE=50;var PLATFORMS=["web","pc","flutter","ios","android","miniprogram","backend"];var MAX_BACKOFF_MS=3e4;var Tracker=class{constructor(opts){__publicField(this,"queue",[]);__publicField(this,"timer",null);__publicField(this,"superProps",{});__publicField(this,"identity");__publicField(this,"persistence");__publicField(this,"send");__publicField(this,"endpoint");__publicField(this,"writeKey");__publicField(this,"platform");__publicField(this,"appVersion");__publicField(this,"maxBatch");__publicField(this,"flushMs");__publicField(this,"maxQueueSize");__publicField(this,"flushing",false);__publicField(this,"retryCount",0);var _a,_b,_c,_d,_e,_f,_g;this.endpoint=opts.endpoint;this.writeKey=opts.writeKey;this.platform=(_a=opts.platform)==null?void 0:_a.trim().toLowerCase();this.appVersion=opts.appVersion;this.maxBatch=(_b=opts.maxBatch)!=null?_b:5;this.flushMs=(_c=opts.flushMs)!=null?_c:5e3;this.maxQueueSize=(_d=opts.maxQueueSize)!=null?_d:500;this.send=(_e=opts.sender)!=null?_e:defaultFetchSender;this.identity=new Identity((_f=opts.storage)!=null?_f:webStorage());if(opts.distinctId)this.identity.setAnonymousId(opts.distinctId);this.persistence=opts.persistence===false?null:(_g=opts.persistence)!=null?_g:indexedDbPersistence({limit:this.maxQueueSize});void this.restore();if(this.platform&&!PLATFORMS.includes(this.platform)){console.error(`[tracker] platform "${this.platform}" 不在受控端列表里,按端分析时这批数据会自成一端。可选值:${PLATFORMS.join(" / ")}(微信小程序是 miniprogram,不是 wechat)`)}if(typeof document!=="undefined"){document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="hidden")this.flush(true)});if(typeof window!=="undefined"){window.addEventListener("pagehide",()=>this.flush(true))}}}restore(){return __async(this,null,function*(){if(!this.persistence)return;const saved=yield this.persistence.load();const known=new Set(this.queue.map(e=>e.eventId));const revived=saved.filter(e=>(e==null?void 0:e.eventId)&&!known.has(e.eventId));if(!revived.length)return;this.queue.unshift(...revived);this.trim();void this.flush()})}register(props){Object.assign(this.superProps,props)}identify(id){if(this.identity.identify(id))this.enqueue("$identify",{})}reset(){this.identity.reset()}getDistinctId(){return this.identity.snapshot().distinctId}getAnonymousId(){return this.identity.snapshot().anonymousId}getSessionId(){return this.identity.snapshot().sessionId}get pending(){return this.queue.length}dispose(){if(this.timer){clearTimeout(this.timer);this.timer=null}}track(name,properties){this.enqueue(name,properties!=null?properties:{})}trackUnsafe(name,properties={}){this.enqueue(name,properties)}captureAs(who,name,properties={}){this.enqueue(name,properties,who)}enqueue(name,properties,override){var _a,_b;if(!override)this.identity.touch();const who=override!=null?override:this.identity.snapshot();const raw={eventId:uuid(),eventName:name,distinctId:who.distinctId,anonymousId:who.anonymousId,userId:(_a=who.userId)!=null?_a:void 0,sessionId:who.sessionId,platform:this.platform,appVersion:this.appVersion,clientTime:new Date().toISOString(),properties:__spreadProps(__spreadValues(__spreadValues({},this.superProps),properties),{$sdk_name:SDK_NAME,$sdk_version:SDK_VERSION,$protocol_version:PROTOCOL_VERSION})};this.queue.push(raw);(_b=this.persistence)==null?void 0:_b.add([{eventId:raw.eventId,savedAt:Date.now(),payload:raw}]);this.trim();if(this.queue.length>=this.maxBatch)this.flush();else this.schedule()}trim(){var _a;const overflow=this.queue.length-this.maxQueueSize;if(overflow>0){const dropped=this.queue.splice(0,overflow);(_a=this.persistence)==null?void 0:_a.remove(dropped.map(e=>e.eventId));console.warn(`[tracker] 队列超过 ${this.maxQueueSize} 条,丢弃最旧的 ${overflow} 条`)}}schedule(delayMs=this.flushMs){if(this.timer)return;this.timer=setTimeout(()=>this.flush(),delayMs)}flush(unloading=false){return __async(this,null,function*(){var _a,_b;if(this.timer){clearTimeout(this.timer);this.timer=null}if(this.queue.length===0||this.flushing&&!unloading)return;this.flushing=true;const batch=this.queue.splice(0,Math.min(MAX_BATCH_SIZE,this.queue.length));const body=JSON.stringify({events:batch,protocolVersion:PROTOCOL_VERSION});const headers={"Content-Type":"application/json","x-write-key":this.writeKey};try{yield this.send(this.endpoint,body,headers,unloading);(_a=this.persistence)==null?void 0:_a.remove(batch.map(e=>e.eventId));this.retryCount=0}catch(err){if((err==null?void 0:err.retryable)!==false){this.queue.unshift(...batch);this.trim();this.retryCount+=1}else{console.warn("[tracker] 丢弃一批(不可重试):",err==null?void 0:err.status);(_b=this.persistence)==null?void 0:_b.remove(batch.map(e=>e.eventId));this.retryCount=0}}finally{this.flushing=false}if(this.queue.length>0&&!unloading){this.schedule(Math.min(this.flushMs*__pow(2,this.retryCount),MAX_BACKOFF_MS))}})}};var defaultFetchSender=(endpoint,body,headers,keepalive)=>__async(null,null,function*(){const res=yield fetch(endpoint,{method:"POST",headers,body,keepalive});if(!res.ok){const e=new Error(`HTTP ${res.status}`);e.status=res.status;e.retryable=res.status>=500||res.status===429;throw e}});var wxSender=(endpoint,body,headers)=>new Promise((resolve,reject)=>{wx.request({url:endpoint,method:"POST",header:headers,data:body,timeout:1e4,success:res=>{if(res.statusCode>=200&&res.statusCode<300)return resolve();const e=new Error(`HTTP ${res.statusCode}`);e.status=res.statusCode;e.retryable=res.statusCode>=500||res.statusCode===429;reject(e)},fail:err=>{const e=new Error(err.errMsg);e.retryable=true;reject(e)}})});function wxStorage(){return{get(key){try{const v=wx.getStorageSync(key);return typeof v==="string"&&v?v:null}catch(e){return null}},set(key,value){try{wx.setStorageSync(key,value)}catch(e){}},remove(key){try{wx.removeStorageSync(key)}catch(e){}}}}var QUEUE_PREFIX="yz_q_";function wxPersistence(limit=500){let known=-1;const keys=()=>{try{return wx.getStorageInfoSync().keys.filter(k=>k.startsWith(QUEUE_PREFIX))}catch(e){return[]}};const readAll=()=>{const out=[];for(const k of keys()){try{const r=wx.getStorageSync(k);if(r==null?void 0:r.eventId)out.push(r)}catch(e){}}return out.sort((a,b)=>a.savedAt-b.savedAt)};return{load(){return __async(this,null,function*(){const all=readAll();known=all.length;return all.map(r=>r.payload)})},add(records){for(const r of records){try{wx.setStorageSync(QUEUE_PREFIX+r.eventId,r)}catch(e){}}known=known<0?keys().length:known+records.length;if(known<=limit)return;const all=readAll();for(const r of all.slice(0,all.length-limit)){try{wx.removeStorageSync(QUEUE_PREFIX+r.eventId)}catch(e){}}known=Math.min(all.length,limit)},remove(eventIds){for(const id of eventIds){try{wx.removeStorageSync(QUEUE_PREFIX+id)}catch(e){}}if(known>0)known=Math.max(0,known-eventIds.length)}}}function wxEnvContext(){try{const i=wx.getSystemInfoSync();const ctx={$runtime:"miniprogram"};if(i.system)ctx.$os=i.system;if(i.model)ctx.$device_model=i.model;if(i.brand)ctx.$device_brand=i.brand;if(i.SDKVersion)ctx.$mp_sdk_version=i.SDKVersion;if(i.version)ctx.$wechat_version=i.version;return ctx}catch(e){return{$runtime:"miniprogram"}}}var SYSTEM_EVENTS=["$pageview","$pageleave","$autocapture","$identify","$experiment_exposure"];var isSystemEvent=name=>SYSTEM_EVENTS.includes(name);var instance=null;function init(options){var _b;const _a=options,{envContext=true,persist=true}=_a,rest=__objRest(_a,["envContext","persist"]);instance=new Tracker(__spreadProps(__spreadValues({},rest),{platform:"miniprogram",sender:wxSender,storage:wxStorage(),persistence:persist?wxPersistence((_b=rest.maxQueueSize)!=null?_b:500):false}));if(envContext)instance.register(wxEnvContext());return instance}function getTracker(){return instance}function ensure(){if(!instance)throw new Error("tracker 未初始化,请先在 app.js 里调用 init()");return instance}function track(name,properties={}){ensure().trackUnsafe(name,properties)}function register(props){ensure().register(props)}function identify(id){ensure().identify(id)}function reset(){ensure().reset()}function flush(){return ensure().flush()}function trackTap(e){var _a,_b;const ds=(_b=(_a=e==null?void 0:e.currentTarget)==null?void 0:_a.dataset)!=null?_b:{};const name=ds.track;if(typeof name!=="string"||!name)return;const props={};for(const k of Object.keys(ds))if(k!=="track")props[k]=ds[k];instance==null?void 0:instance.trackUnsafe(name,props)}function wrap(hooks,name,extra){const original=hooks[name];hooks[name]=function(...args){try{extra(this,args)}catch(e){}return typeof original==="function"?original.apply(this,args):void 0}}function enableAutoTrack(){if(typeof Page==="function"){const originalPage=Page;const patched=(options=>{const enteredAt=new WeakMap;const routeOf=self=>{var _a,_b;return(_b=(_a=self==null?void 0:self.route)!=null?_a:self==null?void 0:self.__route__)!=null?_b:""};wrap(options,"onShow",self=>{enteredAt.set(self,Date.now());instance==null?void 0:instance.track("$pageview",{$url:routeOf(self)})});wrap(options,"onHide",self=>{const at=enteredAt.get(self);if(at===void 0)return;enteredAt.delete(self);instance==null?void 0:instance.track("$pageleave",{$url:routeOf(self),$duration_ms:Date.now()-at})});wrap(options,"onUnload",self=>{const at=enteredAt.get(self);if(at===void 0)return;enteredAt.delete(self);instance==null?void 0:instance.track("$pageleave",{$url:routeOf(self),$duration_ms:Date.now()-at})});return originalPage(options)});Object.assign(patched,originalPage);globalThis.Page=patched}if(typeof App==="function"){const originalApp=App;const patched=(options=>{wrap(options,"onHide",()=>void(instance==null?void 0:instance.flush(true)));return originalApp(options)});Object.assign(patched,originalApp);globalThis.App=patched}}var tracker={init,getTracker,track,register,identify,reset,flush,trackTap,enableAutoTrack};var index_default=tracker;
1
+ "use strict";var __defProp=Object.defineProperty;var __defProps=Object.defineProperties;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropDescs=Object.getOwnPropertyDescriptors;var __getOwnPropNames=Object.getOwnPropertyNames;var __getOwnPropSymbols=Object.getOwnPropertySymbols;var __hasOwnProp=Object.prototype.hasOwnProperty;var __propIsEnum=Object.prototype.propertyIsEnumerable;var __pow=Math.pow;var __defNormalProp=(obj,key,value)=>key in obj?__defProp(obj,key,{enumerable:true,configurable:true,writable:true,value}):obj[key]=value;var __spreadValues=(a,b)=>{for(var prop in b||(b={}))if(__hasOwnProp.call(b,prop))__defNormalProp(a,prop,b[prop]);if(__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(b)){if(__propIsEnum.call(b,prop))__defNormalProp(a,prop,b[prop])}return a};var __spreadProps=(a,b)=>__defProps(a,__getOwnPropDescs(b));var __objRest=(source,exclude)=>{var target={};for(var prop in source)if(__hasOwnProp.call(source,prop)&&exclude.indexOf(prop)<0)target[prop]=source[prop];if(source!=null&&__getOwnPropSymbols)for(var prop of __getOwnPropSymbols(source)){if(exclude.indexOf(prop)<0&&__propIsEnum.call(source,prop))target[prop]=source[prop]}return target};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var __publicField=(obj,key,value)=>__defNormalProp(obj,typeof key!=="symbol"?key+"":key,value);var __async=(__this,__arguments,generator)=>{return new Promise((resolve,reject)=>{var fulfilled=value=>{try{step(generator.next(value))}catch(e){reject(e)}};var rejected=value=>{try{step(generator.throw(value))}catch(e){reject(e)}};var step=x=>x.done?resolve(x.value):Promise.resolve(x.value).then(fulfilled,rejected);step((generator=generator.apply(__this,__arguments)).next())})};var index_exports={};__export(index_exports,{SDK_NAME:()=>SDK_NAME2,SDK_VERSION:()=>SDK_VERSION2,SYSTEM_EVENTS:()=>SYSTEM_EVENTS,default:()=>index_default,enableAutoTrack:()=>enableAutoTrack,flush:()=>flush,getTracker:()=>getTracker,identify:()=>identify,init:()=>init,isSystemEvent:()=>isSystemEvent,refreshRemoteConfig:()=>refreshRemoteConfig,register:()=>register,reset:()=>reset,track:()=>track,trackTap:()=>trackTap,tracker:()=>tracker,wxEnvContext:()=>wxEnvContext,wxPersistence:()=>wxPersistence,wxSender:()=>wxSender,wxStorage:()=>wxStorage});module.exports=__toCommonJS(index_exports);function uuid(){const c=globalThis.crypto;if(typeof(c==null?void 0:c.randomUUID)==="function"){try{return c.randomUUID()}catch(e){}}if(typeof(c==null?void 0:c.getRandomValues)==="function"){try{const b2=c.getRandomValues(new Uint8Array(16));return formatUuid(b2)}catch(e){}}const b=new Uint8Array(16);for(let i=0;i<16;i+=1)b[i]=Math.floor(Math.random()*256);return formatUuid(b)}function formatUuid(b){b[6]=b[6]&15|64;b[8]=b[8]&63|128;const hex=[];for(let i=0;i<16;i+=1)hex.push(b[i].toString(16).padStart(2,"0"));const s=hex.join("");return`${s.slice(0,8)}-${s.slice(8,12)}-${s.slice(12,16)}-${s.slice(16,20)}-${s.slice(20)}`}function memoryStorage(){const m=new Map;return{get:k=>{var _a;return(_a=m.get(k))!=null?_a:null},set:(k,v)=>void m.set(k,v),remove:k=>void m.delete(k)}}function webStorage(){const mem=memoryStorage();let ls=null;try{ls=typeof localStorage!=="undefined"?localStorage:null}catch(e){ls=null}if(!ls)return mem;return{get(k){try{return ls.getItem(k)}catch(e){return mem.get(k)}},set(k,v){try{ls.setItem(k,v)}catch(e){mem.set(k,v)}},remove(k){try{ls.removeItem(k)}catch(e){mem.remove(k)}}}}var STORAGE_KEYS={anonymousId:"yz_anon",userId:"yz_uid",userUuid:"yz_user_uuid",session:"yz_session"};var SESSION_TIMEOUT_MS=30*60*1e3;var TOUCH_PERSIST_MS=60*1e3;function dayKey(ts){const d=new Date(ts);const p=n=>String(n).padStart(2,"0");return`${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}`}var Identity=class{constructor(store,now=Date.now){__publicField(this,"store",store);__publicField(this,"now",now);__publicField(this,"anonymousId");__publicField(this,"userId");__publicField(this,"userUuid");__publicField(this,"session");__publicField(this,"persistedAt");var _a;this.anonymousId=(_a=this.store.get(STORAGE_KEYS.anonymousId))!=null?_a:this.newAnonymousId();this.userId=this.store.get(STORAGE_KEYS.userId)||null;this.userUuid=this.store.get(STORAGE_KEYS.userUuid)||null;this.session=this.loadSession();this.persistedAt=this.session.lastActive}newAnonymousId(){const id=`anon_${uuid()}`;this.store.set(STORAGE_KEYS.anonymousId,id);return id}loadSession(){const raw=this.store.get(STORAGE_KEYS.session);if(raw){try{const s=JSON.parse(raw);if((s==null?void 0:s.id)&&typeof s.lastActive==="number"&&!this.expired(s,this.now()))return s}catch(e){}}return this.startSession(this.now())}expired(s,at){return at-s.lastActive>SESSION_TIMEOUT_MS||s.day!==dayKey(at)}startSession(at){const s={id:uuid(),lastActive:at,day:dayKey(at)};this.store.set(STORAGE_KEYS.session,JSON.stringify(s));this.persistedAt=at;return s}touch(){const at=this.now();if(this.expired(this.session,at)){this.session=this.startSession(at);return}this.session.lastActive=at;if(at-this.persistedAt>=TOUCH_PERSIST_MS){this.store.set(STORAGE_KEYS.session,JSON.stringify(this.session));this.persistedAt=at}}identify(userId,options){var _a;const id=String(userId!=null?userId:"").trim();if(!id)return false;const userChanged=id!==this.userId;const uuidWasProvided=(options==null?void 0:options.userUuid)!==void 0;const nextUuid=uuidWasProvided?String((_a=options.userUuid)!=null?_a:"").trim()||null:this.userUuid;const uuidChanged=nextUuid!==this.userUuid;if(!userChanged&&!uuidChanged)return false;this.userId=id;this.store.set(STORAGE_KEYS.userId,id);this.userUuid=userChanged&&!uuidWasProvided?null:nextUuid;if(this.userUuid)this.store.set(STORAGE_KEYS.userUuid,this.userUuid);else this.store.remove(STORAGE_KEYS.userUuid);return true}reset(anonymousId){this.userId=null;this.store.remove(STORAGE_KEYS.userId);this.userUuid=null;this.store.remove(STORAGE_KEYS.userUuid);const sharedAnonymousId=anonymousId==null?void 0:anonymousId.trim();if(sharedAnonymousId){this.anonymousId=sharedAnonymousId;this.store.set(STORAGE_KEYS.anonymousId,sharedAnonymousId)}else{this.anonymousId=this.newAnonymousId()}this.session=this.startSession(this.now())}snapshot(){var _a;return{distinctId:(_a=this.userId)!=null?_a:this.anonymousId,distinctIdType:this.userId?"user_id":"anonymous_id",anonymousId:this.anonymousId,userId:this.userId,userUuid:this.userUuid,sessionId:this.session.id}}setAnonymousId(id){this.anonymousId=id;this.store.set(STORAGE_KEYS.anonymousId,id)}};var DB_NAME="yz_tracker";var STORE="queue";var DEFAULT_LIMIT=500;function openDb(dbName){return new Promise((resolve,reject)=>{const req=indexedDB.open(dbName,1);req.onupgradeneeded=()=>{const db=req.result;if(!db.objectStoreNames.contains(STORE)){db.createObjectStore(STORE,{keyPath:"eventId"}).createIndex("savedAt","savedAt")}};req.onsuccess=()=>resolve(req.result);req.onerror=()=>reject(req.error);req.onblocked=()=>reject(new Error("indexedDB blocked"))})}function indexedDbPersistence(opts={}){var _a,_b;if(typeof indexedDB==="undefined")return null;const dbName=(_a=opts.dbName)!=null?_a:DB_NAME;const limit=(_b=opts.limit)!=null?_b:DEFAULT_LIMIT;let dbPromise=null;const db=()=>{dbPromise!=null?dbPromise:dbPromise=openDb(dbName);return dbPromise};const write=fn=>__async(null,null,function*(){try{const d=yield db();const tx=d.transaction(STORE,"readwrite");fn(tx.objectStore(STORE))}catch(e){}});return{load(){return __async(this,null,function*(){try{const d=yield db();const tx=d.transaction(STORE,"readonly");const req=tx.objectStore(STORE).index("savedAt").getAll();const rows=yield new Promise((resolve,reject)=>{req.onsuccess=()=>resolve(req.result);req.onerror=()=>reject(req.error)});return rows.map(r=>r.payload)}catch(e){return[]}})},add(records){void write(store=>{for(const r of records)store.put(r);const countReq=store.count();countReq.onsuccess=()=>{const over=countReq.result-limit;if(over<=0)return;let dropped=0;const cur=store.index("savedAt").openCursor();cur.onsuccess=()=>{const c=cur.result;if(!c||dropped>=over)return;c.delete();dropped+=1;c.continue()}}})},remove(eventIds){if(!eventIds.length)return;void write(store=>{for(const id of eventIds)store.delete(id)})}}}var SDK_NAME="@yuanze_dev/tracker";var SDK_VERSION="0.10.0";var PROTOCOL_VERSION=1;var MAX_BATCH_SIZE=50;var PLATFORMS=["web","pc","flutter","ios","android","miniprogram","backend","electron-renderer","electron-main","tauri-web","tauri-rust","node"];var MAX_BACKOFF_MS=3e4;var Tracker=class{constructor(opts){__publicField(this,"queue",[]);__publicField(this,"timer",null);__publicField(this,"superProps",{});__publicField(this,"identity");__publicField(this,"persistence");__publicField(this,"send");__publicField(this,"endpoint");__publicField(this,"writeKey");__publicField(this,"platform");__publicField(this,"appVersion");__publicField(this,"sdkName");__publicField(this,"sdkVersion");__publicField(this,"maxBatch");__publicField(this,"flushMs");__publicField(this,"maxQueueSize");__publicField(this,"flushing",false);__publicField(this,"flushWaiters",[]);__publicField(this,"retryCount",0);__publicField(this,"configVersion",0);__publicField(this,"pageviewHandler",null);__publicField(this,"disposeHandlers",[]);var _a,_b,_c,_d,_e,_f,_g,_h,_i;this.endpoint=opts.endpoint;this.writeKey=opts.writeKey;this.platform=(_a=opts.platform)==null?void 0:_a.trim().toLowerCase();this.appVersion=opts.appVersion;this.sdkName=(_b=opts.sdkName)!=null?_b:SDK_NAME;this.sdkVersion=(_c=opts.sdkVersion)!=null?_c:SDK_VERSION;this.maxBatch=(_d=opts.maxBatch)!=null?_d:5;this.flushMs=(_e=opts.flushMs)!=null?_e:5e3;this.maxQueueSize=(_f=opts.maxQueueSize)!=null?_f:500;this.send=(_g=opts.sender)!=null?_g:defaultFetchSender;this.identity=new Identity((_h=opts.storage)!=null?_h:webStorage());if(opts.distinctId)this.identity.setAnonymousId(opts.distinctId);this.persistence=opts.persistence===false?null:(_i=opts.persistence)!=null?_i:indexedDbPersistence({limit:this.maxQueueSize});void this.restore();if(this.platform&&!PLATFORMS.includes(this.platform)){console.error(`[tracker] platform "${this.platform}" 不在受控端列表里,按端分析时这批数据会自成一端。可选值:${PLATFORMS.join(" / ")}(微信小程序是 miniprogram,不是 wechat)`)}if(typeof document!=="undefined"){document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="hidden")this.flush(true)});if(typeof window!=="undefined"){window.addEventListener("pagehide",()=>this.flush(true))}}}restore(){return __async(this,null,function*(){if(!this.persistence)return;const saved=yield this.persistence.load();const known=new Set(this.queue.map(e=>e.eventId));const revived=saved.filter(e=>(e==null?void 0:e.eventId)&&!known.has(e.eventId));if(!revived.length)return;this.queue.unshift(...revived);this.trim();void this.flush()})}register(props){Object.assign(this.superProps,props)}identify(id,options){if(this.identity.identify(id,options))this.enqueue("$identify",{})}reset(anonymousId){this.identity.reset(anonymousId)}getDistinctId(){return this.identity.snapshot().distinctId}getAnonymousId(){return this.identity.snapshot().anonymousId}getSessionId(){return this.identity.snapshot().sessionId}setConfigVersion(version){if(Number.isInteger(version)&&version>=0)this.configVersion=version}getConfigVersion(){return this.configVersion}get pending(){return this.queue.length}dispose(){if(this.timer){clearTimeout(this.timer);this.timer=null}for(const handler of this.disposeHandlers.splice(0))handler()}addDisposeHandler(handler){this.disposeHandlers.push(handler)}setPageviewHandler(handler){this.pageviewHandler=handler}pageview(input){const url=typeof input==="string"?input:input==null?void 0:input.$url;if(this.pageviewHandler)this.pageviewHandler(url);else if(input&&typeof input==="object")this.track("$pageview",input);else if(url)this.track("$pageview",{$url:url})}track(name,properties){this.enqueue(name,properties!=null?properties:{})}trackUnsafe(name,properties={}){this.enqueue(name,properties)}captureAs(who,name,properties={}){this.enqueue(name,properties,who)}enqueue(name,properties,override){var _a,_b,_c;if(!override)this.identity.touch();const who=override!=null?override:this.identity.snapshot();const raw={eventId:uuid(),eventName:name,distinctId:who.distinctId,distinctIdType:who.distinctIdType,anonymousId:who.anonymousId,userId:(_a=who.userId)!=null?_a:void 0,userUuid:(_b=who.userUuid)!=null?_b:void 0,sessionId:who.sessionId,platform:this.platform,appVersion:this.appVersion,clientTime:new Date().toISOString(),properties:__spreadProps(__spreadValues(__spreadValues({},this.superProps),properties),{$sdk_name:this.sdkName,$sdk_version:this.sdkVersion,$protocol_version:PROTOCOL_VERSION,$config_version:this.configVersion})};this.queue.push(raw);(_c=this.persistence)==null?void 0:_c.add([{eventId:raw.eventId,savedAt:Date.now(),payload:raw}]);this.trim();if(this.queue.length>=this.maxBatch)this.flush();else this.schedule()}trim(){var _a;const overflow=this.queue.length-this.maxQueueSize;if(overflow>0){const dropped=this.queue.splice(0,overflow);(_a=this.persistence)==null?void 0:_a.remove(dropped.map(e=>e.eventId));console.warn(`[tracker] 队列超过 ${this.maxQueueSize} 条,丢弃最旧的 ${overflow} 条`)}}schedule(delayMs=this.flushMs){if(this.timer)return;this.timer=setTimeout(()=>this.flush(),delayMs)}flush(unloading=false){return __async(this,null,function*(){var _a,_b;if(this.timer){clearTimeout(this.timer);this.timer=null}if(this.flushing&&!unloading){yield new Promise(resolve=>this.flushWaiters.push(resolve));if(this.queue.length>0)yield this.flush();return}if(this.queue.length===0)return;this.flushing=true;const batch=this.queue.splice(0,Math.min(MAX_BATCH_SIZE,this.queue.length));const body=JSON.stringify({events:batch,protocolVersion:PROTOCOL_VERSION});const headers={"Content-Type":"application/json","x-write-key":this.writeKey};try{yield this.send(this.endpoint,body,headers,unloading);(_a=this.persistence)==null?void 0:_a.remove(batch.map(e=>e.eventId));this.retryCount=0}catch(err){if((err==null?void 0:err.retryable)!==false){this.queue.unshift(...batch);this.trim();this.retryCount+=1}else{console.warn("[tracker] 丢弃一批(不可重试):",err==null?void 0:err.status);(_b=this.persistence)==null?void 0:_b.remove(batch.map(e=>e.eventId));this.retryCount=0}}finally{this.flushing=false;for(const resolve of this.flushWaiters.splice(0))resolve()}if(this.queue.length>0&&!unloading){this.schedule(Math.min(this.flushMs*__pow(2,this.retryCount),MAX_BACKOFF_MS))}})}};var defaultFetchSender=(endpoint,body,headers,keepalive)=>__async(null,null,function*(){const res=yield fetch(endpoint,{method:"POST",headers,body,keepalive});if(!res.ok){const e=new Error(`HTTP ${res.status}`);e.status=res.status;e.retryable=res.status>=500||res.status===429;throw e}});var DEFAULT_CAPTURE_SETTINGS={captureClicks:true,captureText:true,maxTextLength:64,sampleRate:1,allowSelectors:["a","button",'[role="button"]','[role="link"]','[role="tab"]','[role="menuitem"]','[role="menuitemcheckbox"]','[role="menuitemradio"]','input[type="submit"]','input[type="button"]',"summary"],denySelectors:["[data-no-track]",".yz-no-track"],captureHref:true,captureAriaLabel:true,captureRole:true,captureName:true,captureId:true,captureDataTestId:true,capturePageviews:true,capturePageleave:true,capturePageDuration:true,captureVisibleDuration:false};var bool=v=>typeof v==="boolean";var number=(v,min,max)=>typeof v==="number"&&Number.isFinite(v)&&v>=min&&v<=max;var strings=v=>Array.isArray(v)&&v.length<=50&&v.every(x=>typeof x==="string"&&x.length>0&&x.length<=256);function parseRemoteConfig(input){if(!input||typeof input!=="object")return null;const raw=input;const c=raw.config;if(!c||typeof c!=="object")return null;const config=c;const candidate={captureClicks:config.captureClicks,captureText:config.captureText,maxTextLength:config.maxTextLength,sampleRate:config.sampleRate,allowSelectors:config.allowSelectors,denySelectors:config.denySelectors,captureHref:config.captureHref,captureAriaLabel:config.captureAriaLabel,captureRole:config.captureRole,captureName:config.captureName,captureId:config.captureId,captureDataTestId:config.captureDataTestId,capturePageviews:config.capturePageviews,capturePageleave:config.capturePageleave,capturePageDuration:config.capturePageDuration,captureVisibleDuration:config.captureVisibleDuration};const valid=bool(raw.enabled)&&number(raw.schemaVersion,1,Number.MAX_SAFE_INTEGER)&&Number.isInteger(raw.schemaVersion)&&number(raw.configVersion,0,Number.MAX_SAFE_INTEGER)&&Number.isInteger(raw.configVersion)&&typeof raw.platform==="string"&&number(raw.refreshIntervalSeconds,5,3600)&&bool(candidate.captureClicks)&&bool(candidate.captureText)&&number(candidate.maxTextLength,0,512)&&Number.isInteger(candidate.maxTextLength)&&number(candidate.sampleRate,0,1)&&strings(candidate.allowSelectors)&&strings(candidate.denySelectors)&&bool(candidate.captureHref)&&bool(candidate.captureAriaLabel)&&bool(candidate.captureRole)&&bool(candidate.captureName)&&bool(candidate.captureId)&&bool(candidate.captureDataTestId)&&bool(candidate.capturePageviews)&&bool(candidate.capturePageleave)&&bool(candidate.capturePageDuration)&&bool(candidate.captureVisibleDuration);if(!valid)return null;return{schemaVersion:raw.schemaVersion,configVersion:raw.configVersion,enabled:raw.enabled,platform:raw.platform,refreshIntervalSeconds:raw.refreshIntervalSeconds,config:candidate}}function deriveConfigEndpoint(trackEndpoint){try{const base=typeof location!=="undefined"?location.href:void 0;const url=new URL(trackEndpoint,base);url.pathname=url.pathname.replace(/\/api\/v1\/track\/?$/,"/api/v1/config");url.search="";url.hash="";return url.toString()}catch(e){return trackEndpoint.replace(/\/api\/v1\/track\/?$/,"/api/v1/config")}}function coerceDatasetValue(raw){if(raw===void 0)return void 0;if(raw==="true")return true;if(raw==="false")return false;if(raw==="")return raw;const n=Number(raw);return Number.isFinite(n)&&String(n)===raw?n:raw}var wxSender=(endpoint,body,headers)=>new Promise((resolve,reject)=>{wx.request({url:endpoint,method:"POST",header:headers,data:body,timeout:1e4,success:res=>{if(res.statusCode>=200&&res.statusCode<300)return resolve();const e=new Error(`HTTP ${res.statusCode}`);e.status=res.statusCode;e.retryable=res.statusCode>=500||res.statusCode===429;reject(e)},fail:err=>{const e=new Error(err.errMsg);e.retryable=true;reject(e)}})});function wxStorage(){return{get(key){try{const v=wx.getStorageSync(key);return typeof v==="string"&&v?v:null}catch(e){return null}},set(key,value){try{wx.setStorageSync(key,value)}catch(e){}},remove(key){try{wx.removeStorageSync(key)}catch(e){}}}}var QUEUE_PREFIX="yz_q_";function wxPersistence(limit=500){let known=-1;const keys=()=>{try{return wx.getStorageInfoSync().keys.filter(k=>k.startsWith(QUEUE_PREFIX))}catch(e){return[]}};const readAll=()=>{const out=[];for(const k of keys()){try{const r=wx.getStorageSync(k);if(r==null?void 0:r.eventId)out.push(r)}catch(e){}}return out.sort((a,b)=>a.savedAt-b.savedAt)};return{load(){return __async(this,null,function*(){const all=readAll();known=all.length;return all.map(r=>r.payload)})},add(records){for(const r of records){try{wx.setStorageSync(QUEUE_PREFIX+r.eventId,r)}catch(e){}}known=known<0?keys().length:known+records.length;if(known<=limit)return;const all=readAll();for(const r of all.slice(0,all.length-limit)){try{wx.removeStorageSync(QUEUE_PREFIX+r.eventId)}catch(e){}}known=Math.min(all.length,limit)},remove(eventIds){for(const id of eventIds){try{wx.removeStorageSync(QUEUE_PREFIX+id)}catch(e){}}if(known>0)known=Math.max(0,known-eventIds.length)}}}function wxEnvContext(){try{const i=wx.getSystemInfoSync();const ctx={$runtime:"miniprogram"};if(i.system)ctx.$os=i.system;if(i.model)ctx.$device_model=i.model;if(i.brand)ctx.$device_brand=i.brand;if(i.SDKVersion)ctx.$mp_sdk_version=i.SDKVersion;if(i.version)ctx.$wechat_version=i.version;return ctx}catch(e){return{$runtime:"miniprogram"}}}var SYSTEM_EVENTS=["$pageview","$pageleave","$autocapture","$identify","$experiment_exposure"];var isSystemEvent=name=>SYSTEM_EVENTS.includes(name);var SDK_NAME2="@yuanze_dev/tracker-miniprogram";var SDK_VERSION2="0.8.2";var instance=null;var captureSettings=DEFAULT_CAPTURE_SETTINGS;var captureEnabled=true;var configEtag;var configTimer=null;var configStorage=null;var configOptions=true;var configEndpoint="";var configWriteKey="";function configCacheKey(writeKey){let hash=2166136261;for(const ch of writeKey){hash^=ch.charCodeAt(0);hash=Math.imul(hash,16777619)}return`yz_capture_config_${(hash>>>0).toString(16)}_mini_program`}function applyRemoteConfig(payload){captureSettings=payload.config;captureEnabled=payload.enabled;instance==null?void 0:instance.setConfigVersion(payload.configVersion)}function loadCachedRemoteConfig(){try{const raw=configStorage==null?void 0:configStorage.get(configCacheKey(configWriteKey));if(!raw)return;const cached=JSON.parse(raw);const payload=parseRemoteConfig(cached.payload);if(!payload||payload.platform!=="mini-program")return;configEtag=cached.etag;applyRemoteConfig(payload)}catch(e){}}function refreshRemoteConfig(){if(configOptions===false||!configEndpoint||!configWriteKey)return Promise.resolve();if(configTimer){clearTimeout(configTimer);configTimer=null}const options=typeof configOptions==="object"?configOptions:{};return new Promise(resolve=>{var _a,_b;const url=`${(_a=options.endpoint)!=null?_a:configEndpoint}?platform=mini-program`;wx.request({url,method:"GET",header:__spreadValues({"x-write-key":configWriteKey},configEtag?{"If-None-Match":configEtag}:{}),timeout:(_b=options.timeoutMs)!=null?_b:3e3,success:res=>{var _a2,_b2,_c;if(res.statusCode===304)return;if(res.statusCode<200||res.statusCode>=300)return;let data=res.data;if(typeof data==="string"){try{data=JSON.parse(data)}catch(e){return}}const payload=parseRemoteConfig(data);if(!payload||payload.platform!=="mini-program")return;configEtag=(_c=(_a2=res.header)==null?void 0:_a2.ETag)!=null?_c:(_b2=res.header)==null?void 0:_b2.etag;configStorage==null?void 0:configStorage.set(configCacheKey(configWriteKey),JSON.stringify({etag:configEtag,savedAt:Date.now(),payload}));applyRemoteConfig(payload)},complete:()=>{var _a2;configTimer=setTimeout(()=>void refreshRemoteConfig(),(_a2=options.refreshMs)!=null?_a2:45e3);resolve()}})})}function init(options){var _b;const _a=options,{envContext=true,persist=true,autoTrack=true,remoteConfig=true}=_a,rest=__objRest(_a,["envContext","persist","autoTrack","remoteConfig"]);configStorage=wxStorage();instance=new Tracker(__spreadProps(__spreadValues({},rest),{platform:"miniprogram",sdkName:SDK_NAME2,sdkVersion:SDK_VERSION2,sender:wxSender,storage:configStorage,persistence:persist?wxPersistence((_b=rest.maxQueueSize)!=null?_b:500):false}));if(envContext)instance.register(wxEnvContext());captureSettings=DEFAULT_CAPTURE_SETTINGS;captureEnabled=true;configOptions=remoteConfig;configEndpoint=deriveConfigEndpoint(rest.endpoint);configWriteKey=rest.writeKey;if(remoteConfig!==false)loadCachedRemoteConfig();if(autoTrack)enableAutoTrack();if(remoteConfig!==false)void refreshRemoteConfig();return instance}function getTracker(){return instance}function ensure(){if(!instance)throw new Error("tracker 未初始化,请先在 app.js 里调用 init()");return instance}function track(name,properties={}){ensure().trackUnsafe(name,properties)}function register(props){ensure().register(props)}function identify(id,options){ensure().identify(id,options)}function reset(){ensure().reset()}function flush(){return ensure().flush()}function trackTap(e){var _a,_b;const ds=(_b=(_a=e==null?void 0:e.currentTarget)==null?void 0:_a.dataset)!=null?_b:{};const name=ds.track;if(typeof name!=="string"||!name)return;const props={};for(const k of Object.keys(ds)){if(k==="track")continue;const v=ds[k];props[k]=typeof v==="string"?coerceDatasetValue(v):v}instance==null?void 0:instance.trackUnsafe(name,props)}function wrap(hooks,name,extra){const original=hooks[name];hooks[name]=function(...args){try{extra(this,args)}catch(e){}return typeof original==="function"?original.apply(this,args):void 0}}function enableAutoTrack(){if(typeof Page==="function"&&!Page.__yzAutoTrack){const originalPage=Page;const patched=(options=>{const enteredAt=new WeakMap;const routeOf=self=>{var _a,_b;return(_b=(_a=self==null?void 0:self.route)!=null?_a:self==null?void 0:self.__route__)!=null?_b:""};wrap(options,"onShow",self=>{if(!captureEnabled||!captureSettings.capturePageviews)return;enteredAt.set(self,Date.now());instance==null?void 0:instance.track("$pageview",{$url:routeOf(self)})});wrap(options,"onHide",self=>{const at=enteredAt.get(self);if(at===void 0)return;enteredAt.delete(self);if(!captureEnabled||!captureSettings.capturePageleave)return;instance==null?void 0:instance.track("$pageleave",__spreadValues({$url:routeOf(self)},captureSettings.capturePageDuration?{$duration_ms:Date.now()-at}:{}))});wrap(options,"onUnload",self=>{const at=enteredAt.get(self);if(at===void 0)return;enteredAt.delete(self);if(!captureEnabled||!captureSettings.capturePageleave)return;instance==null?void 0:instance.track("$pageleave",__spreadValues({$url:routeOf(self)},captureSettings.capturePageDuration?{$duration_ms:Date.now()-at}:{}))});return originalPage(options)});Object.assign(patched,originalPage);patched.__yzAutoTrack=true;globalThis.Page=patched}if(typeof App==="function"&&!App.__yzAutoTrack){const originalApp=App;const patched=(options=>{wrap(options,"onHide",()=>void(instance==null?void 0:instance.flush(true)));wrap(options,"onShow",()=>void refreshRemoteConfig());return originalApp(options)});Object.assign(patched,originalApp);patched.__yzAutoTrack=true;globalThis.App=patched}}var tracker={init,getTracker,track,register,identify,reset,flush,trackTap,enableAutoTrack,refreshRemoteConfig};var index_default=tracker;
package/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export type TrackerInstance = {
4
4
  track(name: string, properties?: Record<string, unknown>): void;
5
5
  trackUnsafe(name: string, properties?: Record<string, unknown>): void;
6
6
  register(props: Record<string, unknown>): void;
7
- identify(id: string): void;
7
+ identify(id: string, options?: IdentifyOptions): void;
8
8
  reset(): void;
9
9
  flush(unloading?: boolean): Promise<void>;
10
10
  getDistinctId(): string;
@@ -13,6 +13,14 @@ export type TrackerInstance = {
13
13
  readonly pending: number;
14
14
  };
15
15
 
16
+ export type IdentifyOptions = {
17
+ /** 展示给用户的靓号。distinct_id 仍使用业务数据库 user_id。 */
18
+ userUuid?: string;
19
+ };
20
+
21
+ export declare const SDK_NAME: "@yuanze_dev/tracker-miniprogram";
22
+ export declare const SDK_VERSION: "0.8.2";
23
+
16
24
  export type InitOptions = {
17
25
  /** 如 https://track.example.com/api/v1/track。域名要先加进小程序后台的 request 合法域名 */
18
26
  endpoint: string;
@@ -28,13 +36,17 @@ export type InitOptions = {
28
36
  envContext?: boolean;
29
37
  /** 关掉队列持久化。默认开 —— 小程序被杀掉时没有卸载回调,这是唯一的兜底 */
30
38
  persist?: boolean;
39
+ /** 默认随 init 安装 Page/App 生命周期包装 */
40
+ autoTrack?: boolean;
41
+ /** 默认开启;false 仅用于开发或紧急熔断 */
42
+ remoteConfig?: boolean | { endpoint?: string; refreshMs?: number; timeoutMs?: number };
31
43
  };
32
44
 
33
45
  export declare function init(options: InitOptions): TrackerInstance;
34
46
  export declare function getTracker(): TrackerInstance | null;
35
47
  export declare function track(name: string, properties?: Record<string, unknown>): void;
36
48
  export declare function register(props: Record<string, unknown>): void;
37
- export declare function identify(id: string): void;
49
+ export declare function identify(id: string, options?: IdentifyOptions): void;
38
50
  export declare function reset(): void;
39
51
  export declare function flush(): Promise<void>;
40
52
 
@@ -43,6 +55,7 @@ export declare function trackTap(e: { currentTarget?: { dataset?: Record<string,
43
55
 
44
56
  /** 打开自动采集($pageview / $pageleave / 切后台补发)。必须在 App()/Page() 之前调用 */
45
57
  export declare function enableAutoTrack(): void;
58
+ export declare function refreshRemoteConfig(): Promise<void>;
46
59
 
47
60
  export declare const SYSTEM_EVENTS: readonly string[];
48
61
  export declare function isSystemEvent(name: string): boolean;
@@ -85,5 +98,6 @@ export declare const tracker: {
85
98
  flush: typeof flush;
86
99
  trackTap: typeof trackTap;
87
100
  enableAutoTrack: typeof enableAutoTrack;
101
+ refreshRemoteConfig: typeof refreshRemoteConfig;
88
102
  };
89
103
  export default tracker;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuanze_dev/tracker-miniprogram",
3
- "version": "0.7.0",
3
+ "version": "0.8.2",
4
4
  "description": "原则数据埋点 SDK · 微信小程序",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",