@yuanze_dev/tracker-miniprogram 0.7.1 → 0.9.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.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.1";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}});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 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")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"){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,dispose:()=>dispose,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 normalizeSnapshot(snapshot){var _a,_b,_c,_d,_e;const anonymousId=String((_a=snapshot==null?void 0:snapshot.anonymousId)!=null?_a:"").trim();const sessionId=String((_b=snapshot==null?void 0:snapshot.sessionId)!=null?_b:"").trim();const userId=String((_c=snapshot==null?void 0:snapshot.userId)!=null?_c:"").trim()||null;const userUuid=userId?String((_d=snapshot==null?void 0:snapshot.userUuid)!=null?_d:"").trim()||null:null;const distinctId=userId!=null?userId:anonymousId;const distinctIdType=userId?"user_id":"anonymous_id";if(!anonymousId||!sessionId)return null;if(String((_e=snapshot==null?void 0:snapshot.distinctId)!=null?_e:"").trim()!==distinctId)return null;if((snapshot==null?void 0:snapshot.distinctIdType)!==distinctIdType)return null;return{anonymousId,userId,userUuid,sessionId}}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,initialSnapshot){__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;const initial=initialSnapshot?normalizeSnapshot(initialSnapshot):null;if(initial){this.anonymousId=initial.anonymousId;this.userId=initial.userId;this.userUuid=initial.userUuid;const at=this.now();this.session={id:initial.sessionId,lastActive:at,day:dayKey(at)};this.persistSnapshot()}else{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}persistSnapshot(){this.store.set(STORAGE_KEYS.anonymousId,this.anonymousId);if(this.userId)this.store.set(STORAGE_KEYS.userId,this.userId);else this.store.remove(STORAGE_KEYS.userId);if(this.userUuid)this.store.set(STORAGE_KEYS.userUuid,this.userUuid);else this.store.remove(STORAGE_KEYS.userUuid);this.store.set(STORAGE_KEYS.session,JSON.stringify(this.session))}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}}applySnapshot(snapshot){const next=normalizeSnapshot(snapshot);if(!next)return false;const before=this.snapshot();const at=this.now();this.anonymousId=next.anonymousId;this.userId=next.userId;this.userUuid=next.userUuid;this.session={id:next.sessionId,lastActive:at,day:dayKey(at)};this.persistSnapshot();this.persistedAt=at;const after=this.snapshot();return before.anonymousId!==after.anonymousId||before.userId!==after.userId||before.userUuid!==after.userUuid||before.sessionId!==after.sessionId}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.15.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 documentPageInstanceId;function currentPageInstanceId(){if(typeof window==="undefined"||typeof document==="undefined")return void 0;documentPageInstanceId!=null?documentPageInstanceId:documentPageInstanceId=uuid();return documentPageInstanceId}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,"pageInstanceId");__publicField(this,"flushing",false);__publicField(this,"flushWaiters",[]);__publicField(this,"retryCount",0);__publicField(this,"configVersion",0);__publicField(this,"pageviewHandler",null);__publicField(this,"diagnosticsBridge",null);__publicField(this,"disposeHandlers",[]);__publicField(this,"identityChangeHandlers",[]);var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j;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.pageInstanceId=currentPageInstanceId();this.send=(_g=opts.sender)!=null?_g:defaultFetchSender;this.identity=new Identity((_h=opts.storage)!=null?_h:webStorage(),Date.now,opts.initialIdentity);if(opts.distinctId&&!opts.initialIdentity)this.identity.setAnonymousId(opts.distinctId);this.superProps=__spreadValues({},(_i=opts.initialProperties)!=null?_i:{});this.persistence=opts.persistence===false?null:(_j=opts.persistence)!=null?_j: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"){const onVisibilityChange=()=>{if(document.visibilityState==="hidden")this.flush(true)};document.addEventListener("visibilitychange",onVisibilityChange);this.addDisposeHandler(()=>document.removeEventListener("visibilitychange",onVisibilityChange));if(typeof window!=="undefined"){const onPageHide=()=>this.flush(true);window.addEventListener("pagehide",onPageHide);this.addDisposeHandler(()=>window.removeEventListener("pagehide",onPageHide))}}}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){const before=this.identity.snapshot();if(!this.identity.identify(id,options))return;this.enqueue("$identify",{});const after=this.identity.snapshot();for(const handler of this.identityChangeHandlers)handler(before,after)}reset(anonymousId){const before=this.identity.snapshot();this.identity.reset(anonymousId);const after=this.identity.snapshot();for(const handler of this.identityChangeHandlers)handler(before,after)}getDistinctId(){return this.identity.snapshot().distinctId}getAnonymousId(){return this.identity.snapshot().anonymousId}getSessionId(){return this.identity.snapshot().sessionId}getPageInstanceId(){return this.pageInstanceId}getIdentitySnapshot(){return this.identity.snapshot()}touchIdentity(){const before=this.identity.snapshot();this.identity.touch();const after=this.identity.snapshot();if(before.sessionId!==after.sessionId){for(const handler of this.identityChangeHandlers)handler(before,after)}return after}applyIdentitySnapshot(snapshot){const before=this.identity.snapshot();const changed=this.identity.applySnapshot(snapshot);if(!changed)return false;const after=this.identity.snapshot();for(const handler of this.identityChangeHandlers)handler(before,after);return true}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}this.diagnosticsBridge=null;for(const handler of this.disposeHandlers.splice(0))handler()}addDisposeHandler(handler){this.disposeHandlers.push(handler)}addIdentityChangeHandler(handler){this.identityChangeHandlers.push(handler);const remove=()=>{this.identityChangeHandlers=this.identityChangeHandlers.filter(candidate=>candidate!==handler)};this.addDisposeHandler(remove);return remove}setPageviewHandler(handler){this.pageviewHandler=handler}setDiagnosticsBridge(bridge){this.diagnosticsBridge=bridge}captureException(error,options){var _a,_b;return(_b=(_a=this.diagnosticsBridge)==null?void 0:_a.captureException(error,options))!=null?_b:null}log(level,message,options){var _a,_b;return(_b=(_a=this.diagnosticsBridge)==null?void 0:_a.log(level,message,options))!=null?_b:null}flushDiagnostics(){var _a,_b;return(_b=(_a=this.diagnosticsBridge)==null?void 0:_a.flush())!=null?_b:Promise.resolve()}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={},options={}){this.enqueue(name,properties,who,options)}enqueue(name,properties,override,options={}){var _a,_b,_c,_d;const who=override!=null?override:this.touchIdentity();const raw={eventId:(_a=options.eventId)!=null?_a:uuid(),eventName:name,distinctId:who.distinctId,distinctIdType:who.distinctIdType,anonymousId:who.anonymousId,userId:(_b=who.userId)!=null?_b:void 0,userUuid:(_c=who.userUuid)!=null?_c:void 0,sessionId:who.sessionId,pageInstanceId:this.pageInstanceId,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);(_d=this.persistence)==null?void 0:_d.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,captureTitle: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);var integer=(v,min,max)=>number(v,min,max)&&Number.isInteger(v);var stringList=(v,maxItems,maxLength)=>Array.isArray(v)&&v.length<=maxItems&&v.every(x=>typeof x==="string"&&x.length>0&&x.length<=maxLength);var object=v=>v&&typeof v==="object"&&!Array.isArray(v)?v:{};function isValidHttpsOrigin(value){if(typeof value!=="string")return false;try{const url=new URL(value);return url.protocol==="https:"&&url.origin===value}catch(e){return false}}function parseReplayConfig(input){var _a,_b,_c;if(!input||typeof input!=="object")return null;const raw=input;const settings=object(raw.settings);const versions=object(raw.configVersionSet);const appVersions=object(settings.appVersions);const errorSampling=object(settings.errorSampling);const recording=object(settings.recording);const pages=object(settings.pages);const privacy=object(settings.privacy);const capture=object(settings.capture);const upload=object(settings.upload);const legacyQuota=object(settings.quota);const maxSessionBytes=(_a=settings.maxSessionBytes)!=null?_a:legacyQuota.maxSessionBytes;const uploadOrigins=(_b=raw.uploadOrigins)!=null?_b:[];const checkpointMaxBytes=(_c=recording.checkpointMaxBytes)!=null?_c:4*1024*1024;if(!bool(raw.enabled)||!bool(raw.supported)||raw.recorderKind!=="rrweb"||raw.replayFormat!=="rrweb-v1"||typeof raw.samplingSalt!=="string"||!stringList(uploadOrigins,10,512)||!uploadOrigins.every(isValidHttpsOrigin)||!integer(raw.schemaVersion,1,Number.MAX_SAFE_INTEGER)||!integer(versions.system,0,Number.MAX_SAFE_INTEGER)||!integer(versions.project,0,Number.MAX_SAFE_INTEGER)||!integer(versions.environment,0,Number.MAX_SAFE_INTEGER)||!bool(settings.enabled)||!bool(settings.emergencyDisabled)||!number(settings.sampleRate,0,1)||!stringList(appVersions.include,100,100)||!stringList(appVersions.exclude,100,100)||!bool(errorSampling.enabled)||errorSampling.mode!=="after-error"&&errorSampling.mode!=="rolling-buffer"||!integer(errorSampling.rollingBufferSeconds,5,120)||!integer(recording.maxSessionMinutes,1,720)||!integer(recording.maxEvents,100,2e6)||!integer(recording.chunkSeconds,2,60)||!integer(recording.chunkMaxBytes,64*1024,2*1024*1024)||!integer(checkpointMaxBytes,256*1024,16*1024*1024)||!integer(recording.checkpointSeconds,10,120)||!integer(recording.localQueueMaxBytes,1024*1024,200*1024*1024)||!integer(recording.stopAfterBackgroundMinutes,1,120)||!stringList(pages.include,50,512)||!stringList(pages.exclude,100,512)||!bool(privacy.maskAllInputs)||!stringList(privacy.maskSelectors,100,256)||!stringList(privacy.blockSelectors,100,256)||!stringList(privacy.redactUrlParams,100,100)||!bool(capture.canvas)||!bool(capture.inlineImages)||!bool(capture.collectFonts)||!bool(capture.crossOriginIframes)||!integer(upload.concurrency,1,6)||!integer(upload.timeoutSeconds,5,120)||!integer(upload.maxRetries,0,12)||!integer(upload.retryBaseMs,100,1e4)||!integer(upload.localRetryDays,1,30)||!integer(maxSessionBytes,1024*1024,2*1024*1024*1024))return null;return{schemaVersion:raw.schemaVersion,enabled:raw.enabled,supported:raw.supported,recorderKind:"rrweb",replayFormat:"rrweb-v1",uploadOrigins,samplingSalt:raw.samplingSalt,configVersionSet:{system:versions.system,project:versions.project,environment:versions.environment},settings:{enabled:settings.enabled,emergencyDisabled:settings.emergencyDisabled,sampleRate:settings.sampleRate,appVersions:{include:appVersions.include,exclude:appVersions.exclude},errorSampling:{enabled:errorSampling.enabled,mode:errorSampling.mode,rollingBufferSeconds:errorSampling.rollingBufferSeconds},recording:{maxSessionMinutes:recording.maxSessionMinutes,maxEvents:recording.maxEvents,chunkSeconds:recording.chunkSeconds,chunkMaxBytes:recording.chunkMaxBytes,checkpointMaxBytes,checkpointSeconds:recording.checkpointSeconds,localQueueMaxBytes:recording.localQueueMaxBytes,stopAfterBackgroundMinutes:recording.stopAfterBackgroundMinutes},pages:{include:pages.include,exclude:pages.exclude},privacy:{maskAllInputs:privacy.maskAllInputs,maskSelectors:privacy.maskSelectors,blockSelectors:privacy.blockSelectors,redactUrlParams:privacy.redactUrlParams},capture:{canvas:capture.canvas,inlineImages:capture.inlineImages,collectFonts:capture.collectFonts,crossOriginIframes:capture.crossOriginIframes},upload:{concurrency:upload.concurrency,timeoutSeconds:upload.timeoutSeconds,maxRetries:upload.maxRetries,retryBaseMs:upload.retryBaseMs,localRetryDays:upload.localRetryDays},maxSessionBytes}}}var DIAGNOSTIC_LEVELS=new Set(["debug","info","warn","error","fatal"]);function parseDiagnosticsConfig(input){if(!input||typeof input!=="object")return null;const raw=input;const settings=object(raw.settings);const versions=object(raw.configVersionSet);const errors=object(settings.errors);const logs=object(settings.logs);const context=object(settings.context);const upload=object(settings.upload);const privacy=object(settings.privacy);const levels=logs.levels;if(!integer(raw.schemaVersion,1,Number.MAX_SAFE_INTEGER)||!bool(raw.enabled)||!bool(raw.supported)||typeof raw.endpointPath!=="string"||!raw.endpointPath.startsWith("/")||raw.endpointPath.length>512||!integer(versions.system,0,Number.MAX_SAFE_INTEGER)||!integer(versions.project,0,Number.MAX_SAFE_INTEGER)||!integer(versions.environment,0,Number.MAX_SAFE_INTEGER)||!number(errors.sampleRate,0,1)||!bool(errors.captureUnhandled)||!bool(errors.captureHandled)||!Array.isArray(levels)||levels.length>5||!levels.every(level=>typeof level==="string"&&DIAGNOSTIC_LEVELS.has(level))||new Set(levels).size!==levels.length||!number(logs.sampleRate,0,1)||!integer(context.windowSeconds,5,300)||!integer(context.maxEntries,10,200)||!integer(context.maxBytes,16*1024,1024*1024)||!integer(upload.batchSize,1,100)||!integer(upload.batchMaxBytes,16*1024,1024*1024)||!integer(upload.flushMs,500,6e4)||!integer(upload.timeoutMs,1e3,3e4)||!integer(upload.maxRetries,0,12)||!integer(upload.offlineMaxBytes,256*1024,50*1024*1024)||!integer(upload.offlineTtlHours,1,168)||!integer(privacy.maxMessageBytes,128,4096)||!integer(privacy.maxStackBytes,4096,256*1024)||!stringList(privacy.denyKeys,100,128)||!stringList(privacy.redactUrlParams,100,128))return null;return{schemaVersion:raw.schemaVersion,enabled:raw.enabled,supported:raw.supported,endpointPath:raw.endpointPath,configVersionSet:{system:versions.system,project:versions.project,environment:versions.environment},settings:{errors:{sampleRate:errors.sampleRate,captureUnhandled:errors.captureUnhandled,captureHandled:errors.captureHandled},logs:{levels:[...levels],sampleRate:logs.sampleRate},context:{windowSeconds:context.windowSeconds,maxEntries:context.maxEntries,maxBytes:context.maxBytes},upload:{batchSize:upload.batchSize,batchMaxBytes:upload.batchMaxBytes,flushMs:upload.flushMs,timeoutMs:upload.timeoutMs,maxRetries:upload.maxRetries,offlineMaxBytes:upload.offlineMaxBytes,offlineTtlHours:upload.offlineTtlHours},privacy:{maxMessageBytes:privacy.maxMessageBytes,maxStackBytes:privacy.maxStackBytes,denyKeys:[...privacy.denyKeys],redactUrlParams:[...privacy.redactUrlParams]}}}}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,captureTitle:config.captureTitle===void 0?true:config.captureTitle,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.captureTitle)&&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;const replay=parseReplayConfig(raw.replay);const diagnostics=parseDiagnosticsConfig(raw.diagnostics);return __spreadValues(__spreadValues({schemaVersion:raw.schemaVersion,configVersion:raw.configVersion,enabled:raw.enabled,platform:raw.platform,refreshIntervalSeconds:raw.refreshIntervalSeconds,config:candidate},raw.replay===void 0?{}:{replay}),raw.diagnostics===void 0?{}:{diagnostics})}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=["$app_start","$app_foreground","$app_background","$pageview","$pageleave","$autocapture","$identify","$replay_diagnostic","$replay_focus","$experiment_exposure"];var isSystemEvent=name=>SYSTEM_EVENTS.includes(name);var SDK_NAME2="@yuanze_dev/tracker-miniprogram";var SDK_VERSION2="0.9.0";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="";var configGeneration=0;var configRequest=null;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(configRequest)return configRequest;if(configTimer){clearTimeout(configTimer);configTimer=null}const options=typeof configOptions==="object"?configOptions:{};const generation=configGeneration;const endpoint=configEndpoint;const writeKey=configWriteKey;const storage=configStorage;const etag=configEtag;const request=new Promise(resolve=>{var _a,_b;let settled=false;const complete=()=>{var _a2;if(settled)return;settled=true;if(generation===configGeneration&&configOptions!==false){configTimer=setTimeout(()=>{void refreshRemoteConfig()},(_a2=options.refreshMs)!=null?_a2:45e3)}resolve()};try{const url=`${(_a=options.endpoint)!=null?_a:endpoint}?platform=mini-program`;wx.request({url,method:"GET",header:__spreadValues({"x-write-key":writeKey},etag?{"If-None-Match":etag}:{}),timeout:(_b=options.timeoutMs)!=null?_b:3e3,success:res=>{var _a2,_b2,_c;if(generation!==configGeneration)return;try{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;storage==null?void 0:storage.set(configCacheKey(writeKey),JSON.stringify({etag:configEtag,savedAt:Date.now(),payload}));applyRemoteConfig(payload)}catch(e){}},fail:complete,complete})}catch(e){complete()}});const tracked=request.finally(()=>{if(configRequest===tracked)configRequest=null});configRequest=tracked;return tracked}function dispose(){configGeneration+=1;if(configTimer){clearTimeout(configTimer);configTimer=null}configRequest=null;configOptions=false;configEndpoint="";configWriteKey="";configEtag=void 0;configStorage=null;captureSettings=DEFAULT_CAPTURE_SETTINGS;captureEnabled=true;const current=instance;instance=null;current==null?void 0:current.dispose();disableOwnedAutoTrackRuntime()}function init(options){var _b;dispose();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;configEtag=void 0;configOptions=remoteConfig;configEndpoint=deriveConfigEndpoint(rest.endpoint);configWriteKey=rest.writeKey;if(remoteConfig!==false)loadCachedRemoteConfig();if(autoTrack)enableAutoTrack();else bindAutoTrackRuntime(false);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)}var AUTO_TRACK_RUNTIME_KEY=Symbol.for("@yuanze_dev/tracker-miniprogram:auto-track-runtime");var MODULE_RUNTIME_OWNER={};function autoTrackRuntimeSlot(){var _a;return(_a=globalThis[AUTO_TRACK_RUNTIME_KEY])!=null?_a:null}function disableOwnedAutoTrackRuntime(){const runtime=autoTrackRuntimeSlot();if((runtime==null?void 0:runtime.owner)===MODULE_RUNTIME_OWNER)runtime.enabled=false}function bindAutoTrackRuntime(enabled){var _a,_b;const root=globalThis;const runtime=(_a=autoTrackRuntimeSlot())!=null?_a:{owner:null,enabled:false,disposeOwner:null,captureState:()=>({enabled:false,settings:DEFAULT_CAPTURE_SETTINGS}),captureInteraction:()=>void 0,track:()=>void 0,flush:()=>void 0,refresh:()=>void 0};if(runtime.owner&&runtime.owner!==MODULE_RUNTIME_OWNER){try{(_b=runtime.disposeOwner)==null?void 0:_b.call(runtime)}catch(e){}}runtime.owner=MODULE_RUNTIME_OWNER;runtime.enabled=enabled;runtime.disposeOwner=dispose;runtime.captureState=()=>({enabled:runtime.enabled&&captureEnabled,settings:captureSettings});runtime.captureInteraction=(self,event)=>{if(runtime.enabled)captureInteraction(self,event)};runtime.track=(name,properties)=>{if(runtime.enabled)instance==null?void 0:instance.trackUnsafe(name,properties)};runtime.flush=()=>{if(runtime.enabled)void(instance==null?void 0:instance.flush(true))};runtime.refresh=()=>{if(runtime.enabled)void refreshRemoteConfig()};root[AUTO_TRACK_RUNTIME_KEY]=runtime;return runtime}var PAGE_LIFECYCLE_HOOKS=new Set(["onLoad","onShow","onReady","onHide","onUnload","onPullDownRefresh","onReachBottom","onShareAppMessage","onShareTimeline","onAddToFavorites","onPageScroll","onResize","onTabItemTap","onSaveExitState"]);var INTERACTION_WRAPPED=Symbol.for("@yuanze_dev/tracker-miniprogram:interaction-wrapped");var LIFECYCLE_WRAPPED=Symbol.for("@yuanze_dev/tracker-miniprogram:lifecycle-wrapped");function routeOf(self){var _a,_b;const direct=(_a=self==null?void 0:self.route)!=null?_a:self==null?void 0:self.__route__;if(direct)return direct;try{if(typeof getCurrentPages==="function"){const pages=getCurrentPages();const current=(_b=pages[pages.length-1])==null?void 0:_b.route;if(current)return current}}catch(e){}const componentPath=self==null?void 0:self.is;return componentPath?`miniprogram://component/${componentPath}`:"miniprogram://app"}function firstFinite(...values){for(const value of values){if(typeof value==="number"&&Number.isFinite(value))return value}return void 0}function captureInteraction(self,event){var _a,_b,_c,_d,_e,_f;if(!captureEnabled||!captureSettings.captureClicks||!event)return;if(event.type!=="tap"&&event.type!=="longpress"&&event.type!=="longtap")return;const target=event.currentTarget;const dataset=(_a=target==null?void 0:target.dataset)!=null?_a:{};if(typeof dataset.track==="string"&&dataset.track)return;const touch=(_d=(_b=event.changedTouches)==null?void 0:_b[0])!=null?_d:(_c=event.touches)==null?void 0:_c[0];const x=firstFinite((_e=event.detail)==null?void 0:_e.x,touch==null?void 0:touch.clientX,target==null?void 0:target.offsetLeft);const y=firstFinite((_f=event.detail)==null?void 0:_f.y,touch==null?void 0:touch.clientY,target==null?void 0:target.offsetTop);const id=typeof(target==null?void 0:target.id)==="string"&&target.id?target.id:void 0;const route=routeOf(self);const componentPath=self==null?void 0:self.is;instance==null?void 0:instance.track("$autocapture",__spreadValues(__spreadValues(__spreadValues({$tag:componentPath?"component":"miniprogram",$selector:id?`#${id}`:componentPath?`component:${componentPath}`:`miniprogram:${route}`,$url:route,$role:event.type==="tap"?"tap":"longpress"},id?{$element_id:id}:{}),x===void 0?{}:{$x:Math.round(x)}),y===void 0?{}:{$y:Math.round(y)}))}function wrapInteractionMethods(methods,runtime,ignored=new Set){for(const[name,value]of Object.entries(methods)){if(ignored.has(name)||typeof value!=="function")continue;if(value[INTERACTION_WRAPPED])continue;const wrapped=function(...args){try{return value.apply(this,args)}finally{try{runtime.captureInteraction(this,args[0])}catch(e){}}};Object.defineProperty(wrapped,INTERACTION_WRAPPED,{value:true});methods[name]=wrapped}}function wrapPageInteractions(options,runtime){wrapInteractionMethods(options,runtime,PAGE_LIFECYCLE_HOOKS)}function wrapComponentInteractions(options,runtime){const methods=options.methods;if(!methods||typeof methods!=="object"||Array.isArray(methods))return;wrapInteractionMethods(methods,runtime)}function wrap(hooks,name,extra){const original=hooks[name];if(typeof original==="function"&&original[LIFECYCLE_WRAPPED])return;const wrapped=function(...args){try{extra(this,args)}catch(e){}return typeof original==="function"?original.apply(this,args):void 0};Object.defineProperty(wrapped,LIFECYCLE_WRAPPED,{value:true});hooks[name]=wrapped}function enableAutoTrack(){const runtime=bindAutoTrackRuntime(true);if(typeof Page==="function"&&!Page.__yzAutoTrack){const originalPage=Page;const patched=(options=>{const enteredAt=new WeakMap;try{wrap(options,"onShow",self=>{const capture=runtime.captureState();if(!capture.enabled||!capture.settings.capturePageviews)return;enteredAt.set(self,Date.now());runtime.track("$pageview",{$url:routeOf(self)})});wrap(options,"onHide",self=>{const at=enteredAt.get(self);if(at===void 0)return;enteredAt.delete(self);const capture=runtime.captureState();if(!capture.enabled||!capture.settings.capturePageleave)return;runtime.track("$pageleave",__spreadValues({$url:routeOf(self)},capture.settings.capturePageDuration?{$duration_ms:Date.now()-at}:{}))});wrap(options,"onUnload",self=>{const at=enteredAt.get(self);if(at===void 0)return;enteredAt.delete(self);const capture=runtime.captureState();if(!capture.enabled||!capture.settings.capturePageleave)return;runtime.track("$pageleave",__spreadValues({$url:routeOf(self)},capture.settings.capturePageDuration?{$duration_ms:Date.now()-at}:{}))});wrapPageInteractions(options,runtime)}catch(e){}return originalPage(options)});Object.assign(patched,originalPage);patched.__yzAutoTrack=true;globalThis.Page=patched}if(typeof Component==="function"&&!Component.__yzAutoTrack){const originalComponent=Component;const patched=(options=>{try{wrapComponentInteractions(options,runtime)}catch(e){}return originalComponent(options)});Object.assign(patched,originalComponent);patched.__yzAutoTrack=true;globalThis.Component=patched}if(typeof App==="function"&&!App.__yzAutoTrack){const originalApp=App;const patched=(options=>{let launched=false;let foreground=false;let foregroundAt=Date.now();try{wrap(options,"onLaunch",(_self,args)=>{var _a;const launch=(_a=args[0])!=null?_a:{};launched=true;foreground=true;foregroundAt=Date.now();if(runtime.captureState().enabled){runtime.track("$app_start",__spreadValues(__spreadValues({},typeof launch.scene==="number"?{$scene:launch.scene}:{}),typeof launch.path==="string"&&launch.path?{$path:launch.path}:{}))}});wrap(options,"onHide",()=>{if(foreground&&runtime.captureState().enabled){runtime.track("$app_background",{$duration_ms:Math.max(0,Date.now()-foregroundAt),$state:"hidden"})}foreground=false;runtime.flush()});wrap(options,"onShow",(_self,args)=>{var _a;const show=(_a=args[0])!=null?_a:{};if(launched&&!foreground&&runtime.captureState().enabled){runtime.track("$app_foreground",__spreadProps(__spreadValues(__spreadValues({},typeof show.scene==="number"?{$scene:show.scene}:{}),typeof show.path==="string"&&show.path?{$path:show.path}:{}),{$previous_state:"hidden"}))}foreground=true;foregroundAt=Date.now();runtime.refresh()})}catch(e){}return originalApp(options)});Object.assign(patched,originalApp);patched.__yzAutoTrack=true;globalThis.App=patched}}var tracker={init,getTracker,track,register,identify,reset,flush,dispose,trackTap,enableAutoTrack,refreshRemoteConfig};var index_default=tracker;
package/index.d.ts CHANGED
@@ -4,19 +4,97 @@ 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;
11
11
  getAnonymousId(): string;
12
12
  getSessionId(): string;
13
+ getIdentitySnapshot(): IdentitySnapshot;
14
+ touchIdentity(): IdentitySnapshot;
15
+ applyIdentitySnapshot(snapshot: IdentitySnapshot): boolean;
16
+ dispose(): void;
13
17
  readonly pending: number;
14
18
  };
15
19
 
20
+ export type IdentifyOptions = {
21
+ /** 展示给用户的靓号。distinct_id 仍使用业务数据库 user_id。 */
22
+ userUuid?: string;
23
+ };
24
+
25
+ export type IdentitySnapshot = {
26
+ distinctId: string;
27
+ distinctIdType: "anonymous_id" | "user_id";
28
+ anonymousId: string;
29
+ userId: string | null;
30
+ userUuid: string | null;
31
+ sessionId: string;
32
+ };
33
+
34
+ export interface SystemEvents {
35
+ $app_start: { $scene?: number; $path?: string };
36
+ $app_foreground: { $scene?: number; $path?: string; $previous_state?: string };
37
+ $app_background: { $duration_ms?: number; $state?: string };
38
+ $pageview: { $url: string; $title?: string; $referrer?: string };
39
+ $autocapture: {
40
+ $tag: string;
41
+ $selector: string;
42
+ $url: string;
43
+ $text?: string;
44
+ $element_title?: string;
45
+ $href?: string;
46
+ $aria_label?: string;
47
+ $role?: string;
48
+ $name?: string;
49
+ $element_id?: string;
50
+ $data_testid?: string;
51
+ $x?: number;
52
+ $y?: number;
53
+ $button?: number;
54
+ $alt_key?: boolean;
55
+ $ctrl_key?: boolean;
56
+ $meta_key?: boolean;
57
+ $shift_key?: boolean;
58
+ };
59
+ $pageleave: {
60
+ $url: string;
61
+ $duration_ms?: number;
62
+ $visible_duration_ms?: number;
63
+ $title?: string;
64
+ };
65
+ $identify: Record<string, never>;
66
+ $replay_diagnostic: {
67
+ $status: "waiting" | "skipped" | "started" | "failed";
68
+ $reason: string;
69
+ $http_status?: number;
70
+ $error_code?: string;
71
+ };
72
+ $replay_focus: { $url: string; $title?: string };
73
+ $experiment_exposure: { experiment: string; variant: string };
74
+ }
75
+
76
+ export interface ProjectEvents {}
77
+
78
+ export type EventName = keyof SystemEvents | keyof ProjectEvents;
79
+ export type EventProps<K extends EventName> = K extends keyof ProjectEvents
80
+ ? ProjectEvents[K]
81
+ : K extends keyof SystemEvents
82
+ ? SystemEvents[K]
83
+ : never;
84
+
85
+ export declare const SDK_NAME: "@yuanze_dev/tracker-miniprogram";
86
+ export declare const SDK_VERSION: "0.9.0";
87
+
16
88
  export type InitOptions = {
17
89
  /** 如 https://track.example.com/api/v1/track。域名要先加进小程序后台的 request 合法域名 */
18
90
  endpoint: string;
19
91
  writeKey: string;
92
+ /** 由宿主显式指定稳定匿名身份;通常交给 SDK 通过 wx storage 生成和恢复 */
93
+ distinctId?: string;
94
+ /** 需要与另一运行面共享身份时,在首个事件前注入完整快照 */
95
+ initialIdentity?: IdentitySnapshot;
96
+ /** 在首个自动生命周期事件前注册的公共属性;验收时注入 $validation_run_id */
97
+ initialProperties?: Record<string, unknown>;
20
98
  appVersion?: string;
21
99
  /** 攒够多少条就发,默认 5 */
22
100
  maxBatch?: number;
@@ -28,24 +106,42 @@ export type InitOptions = {
28
106
  envContext?: boolean;
29
107
  /** 关掉队列持久化。默认开 —— 小程序被杀掉时没有卸载回调,这是唯一的兜底 */
30
108
  persist?: boolean;
109
+ /** 默认随 init 安装 Page/App 生命周期包装 */
110
+ autoTrack?: boolean;
111
+ /** 默认开启;false 仅用于开发或紧急熔断 */
112
+ remoteConfig?: boolean | { endpoint?: string; refreshMs?: number; timeoutMs?: number };
31
113
  };
32
114
 
33
115
  export declare function init(options: InitOptions): TrackerInstance;
34
116
  export declare function getTracker(): TrackerInstance | null;
35
117
  export declare function track(name: string, properties?: Record<string, unknown>): void;
36
118
  export declare function register(props: Record<string, unknown>): void;
37
- export declare function identify(id: string): void;
119
+ export declare function identify(id: string, options?: IdentifyOptions): void;
38
120
  export declare function reset(): void;
39
121
  export declare function flush(): Promise<void>;
122
+ /** 停止当前 Tracker 和远程配置定时器;主要用于热重载和宿主测试 */
123
+ export declare function dispose(): void;
40
124
 
41
125
  /** 绑到 bindtap,事件名写在 wxml 的 data-track 上 */
42
126
  export declare function trackTap(e: { currentTarget?: { dataset?: Record<string, unknown> } }): void;
43
127
 
44
- /** 打开自动采集($pageview / $pageleave / 切后台补发)。必须在 App()/Page() 之前调用 */
128
+ /** 打开 App/Page 生命周期与 Page/Component tap/longpress 自动采集 */
45
129
  export declare function enableAutoTrack(): void;
130
+ export declare function refreshRemoteConfig(): Promise<void>;
46
131
 
47
- export declare const SYSTEM_EVENTS: readonly string[];
48
- export declare function isSystemEvent(name: string): boolean;
132
+ export declare const SYSTEM_EVENTS: readonly [
133
+ "$app_start",
134
+ "$app_foreground",
135
+ "$app_background",
136
+ "$pageview",
137
+ "$pageleave",
138
+ "$autocapture",
139
+ "$identify",
140
+ "$replay_diagnostic",
141
+ "$replay_focus",
142
+ "$experiment_exposure",
143
+ ];
144
+ export declare function isSystemEvent(name: string): name is keyof SystemEvents;
49
145
 
50
146
  // ---- 适配层。init() 已经接好了,这里导出是给"想自己组装"的场景用 ----
51
147
 
@@ -83,7 +179,9 @@ export declare const tracker: {
83
179
  identify: typeof identify;
84
180
  reset: typeof reset;
85
181
  flush: typeof flush;
182
+ dispose: typeof dispose;
86
183
  trackTap: typeof trackTap;
87
184
  enableAutoTrack: typeof enableAutoTrack;
185
+ refreshRemoteConfig: typeof refreshRemoteConfig;
88
186
  };
89
187
  export default tracker;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuanze_dev/tracker-miniprogram",
3
- "version": "0.7.1",
3
+ "version": "0.9.0",
4
4
  "description": "原则数据埋点 SDK · 微信小程序",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",
@@ -16,4 +16,4 @@
16
16
  "scripts": {
17
17
  "build": "node build.mjs"
18
18
  }
19
- }
19
+ }