@tengence/track-sdk-web 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,25 @@
1
+ import { BaseOptions, ClientReportData, ReportFunction } from "./interface";
2
+ declare global {
3
+ interface Window {
4
+ trackMonitor: {
5
+ report: ReportFunction;
6
+ bindUser: (id: string) => void;
7
+ unBindUser: () => void;
8
+ enableLogger: () => void;
9
+ disableLogger: () => void;
10
+ };
11
+ }
12
+ }
13
+ export declare let options: Required<BaseOptions> | undefined;
14
+ declare const createBrowserClient: (opt: BaseOptions) => {
15
+ client: {
16
+ report: (data: ClientReportData) => void;
17
+ bindUser: (id: string) => void;
18
+ unBindUser: () => void;
19
+ enableLogger: () => void;
20
+ disableLogger: () => void;
21
+ };
22
+ beforeClose: () => void;
23
+ };
24
+ export declare const traceId: string;
25
+ export default createBrowserClient;
package/dist/index.d.ts CHANGED
@@ -1,18 +1,9 @@
1
- import { BaseOptions, ClientReportData, ReportFunction } from "./interface";
2
- declare global {
3
- interface Window {
4
- trackMonitor: {
5
- report: ReportFunction;
6
- realtimeReport: ReportFunction;
7
- bindUser: (id: string) => void;
8
- unBindUser: () => void;
9
- };
10
- }
11
- }
12
- declare const init: (options: BaseOptions) => {
1
+ import { BaseOptions } from './interface';
2
+ declare const init: (opt: BaseOptions) => {
3
+ report: (data: import("./interface").ClientReportData) => void;
13
4
  bindUser: (id: string) => void;
14
5
  unBindUser: () => void;
15
- report: (data: ClientReportData) => void;
16
- realtimeReport: (data: ClientReportData) => void;
6
+ enableLogger: () => void;
7
+ disableLogger: () => void;
17
8
  };
18
9
  export default init;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- const e=!!navigator?.sendBeacon,t=window.requestIdleCallback||window.requestAnimationFrame||(e=>setTimeout(e,17)),n=e=>{"complete"===document.readyState?setTimeout(e):window.addEventListener("pageshow",e,{once:!0,capture:!0})};function r(e,t=150,n=!1){let r=null;return function(...o){const a=this,i=n&&!r;r&&clearTimeout(r),r=setTimeout((()=>{r=null,n||e.apply(a,o)}),t),i&&e.apply(a,o)}}const o=(e,t=300)=>{let n=0;return function(...r){const o=Date.now();o-n>=t&&(n=o,e.apply(this,r))}};function a(e,t=""){if(!e)return t;const n=e.parentElement,{id:r}=e,o=e.tagName.toLowerCase(),i=t?`>${t}`:"";return n&&n!==document.documentElement&&n!==document.body?r?`#${r}${i}`:a(n,`${o}${i}`):`${o}${i}`}const i=()=>{if(window.performance?.navigation)return performance.navigation.type;if(window.performance?.getEntriesByType){const e=performance.getEntriesByType("navigation");if(e.length>0)return e[0].type}return 255},s=e=>{const t=history[e];return function(){const n=t.apply(this,arguments),r=new Event(e);return window.dispatchEvent(r),n}},c=e=>{window.addEventListener("replaceState",(t=>e(t)),!0),window.addEventListener("pushState",(t=>e(t)),!0)},l=e=>{window.addEventListener("popstate",(t=>e(t)),!0)},d=e=>{const t=o((t=>{const n=function(e){if(!e)return;if(["A","INPUT","TEXTAREA","BUTTON"].includes(e.tagName))return console.log("预设的可跟踪元素 ",e),e;if(e.hasAttribute("track-click"))return console.log("带有 track-click 属性的可跟踪元素 ",e),e;const t=e.closest("a, button, [track-click]");return t?(console.log("找到的可跟踪元素 ",t),t):void 0}(t.target);if(!n)return;const r={element_id:n.id,element_content:n.textContent?.trim()||null,element_class_name:n.className||null,element_name:n.getAttribute("name")||null,element_type:n.tagName.toLowerCase(),element_path:a(n),scroll_width:document.documentElement.scrollWidth,scroll_height:document.documentElement.scrollHeight,pageX:t.pageX,pageY:t.pageY,ratio:window.devicePixelRatio||1};e({data_type:"common",event_type:"click",event_detail:r})}));window.addEventListener("click",t,!0)},u=e=>{history.pushState=s("pushState"),history.replaceState=s("replaceState"),(e=>{const t=r((()=>{const{host:t,hostname:n,href:r,protocol:o,origin:a,port:s,pathname:c,search:l,hash:d}=window.location,u={host:t,hostname:n,href:r,protocol:o,origin:a,port:s,pathname:c,search:l,hash:d,title:document.title,language:navigator.language.substring(0,2),user_agent:navigator.userAgent,win_screen:`${window.screen.width}x${window.screen.height}`,doc_screen:`${document.documentElement.clientWidth}x${document.documentElement.clientHeight}`,referrer:document.referrer,type:i()};e({data_type:"common",event_type:"view",event_detail:u})}));n((()=>{t()})),l((()=>{t()})),c((()=>{t()}))})(e),(e=>{let t="",o="",a=0;const i=()=>{if(o&&a){const n=Date.now()-a;n>0&&e({data_type:"common",event_type:"leave",event_detail:{url:o,referrer:t,duration:n}})}a=Date.now(),t=o,o=window.location.href},s=r(i);n((()=>{s()})),l((()=>{s()})),c((()=>{s()})),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState?i():a=Date.now()})),window.addEventListener("pagehide",(()=>{i()}),!0),window.addEventListener("pageshow",(()=>{a=Date.now()}),!0),window.addEventListener("beforeunload",(()=>{i()}),!0)})(e),d(e)};let m=null,h=null;const p="track-expose",w="track-view",g="TRACK_MONITOR_DATA",f="TRACK_MONITOR_USER";let v=null,y=null;const _=(e,t,n)=>({session_id:t.session_id,request_id:t.request_id,spm:t.spm,data_type:t.data_type||"behavior",event_type:t.event_type,event_detail:"string"==typeof t.event_detail?t.event_detail:JSON.stringify(t.event_detail),page_url:location.href,os:window.navigator.platform,user_id:localStorage.getItem(f)||void 0,user_agent:window.navigator.userAgent,screen_width:window.screen.width,screen_height:window.screen.height,lib_version:"1.0.0",lib_type:"js",event_time:(new Date).getTime().toString(),timezone_offset:(new Date).getTimezoneOffset().toString(),site_id:n,channel_id:e}),E=n=>{const{url:r="http://api.mossego.cn/push/track-data",accessKey:o,cacheNumber:a=50,reportInterval:i=3e4,maxCacheSize:s=56,maxRetries:c=10,log:l}=n,d=r.includes("?")?`${r}&ak=${o}`:`${r}?ak=${o}`;let E=0;const b=e=>{try{localStorage.setItem(f,e)}catch(e){console.error("monitor bind user fail: ",e)}},S=()=>{localStorage.removeItem(f)},T=()=>{let e=[];try{e=JSON.parse(localStorage.getItem(g)||"[]")}catch(e){console.error("get monitor data fail: ",e)}return e},A=e=>{try{localStorage.setItem(g,JSON.stringify(e))}catch(t){console.error("save monitor data error: ",e),localStorage.setItem(g,"[]")}},$=t=>{if(l&&console.log("report data ",t),e){const e=((e,t)=>navigator.sendBeacon(e,t))(d,new Blob([JSON.stringify(t)],{type:"application/json"}));if(e)return Promise.resolve()}return(({method:e,url:t,data:n,headers:r={},withCredentials:o=!1})=>new Promise(((a,i)=>{const s=new XMLHttpRequest;s.open(e,t,!0),Object.keys(r).forEach((e=>{s.setRequestHeader(e,r[e])})),s.withCredentials=!!o,s.onreadystatechange=()=>{if(4===s.readyState)if(s.status>=200&&s.status<300)try{const e=JSON.parse(s.responseText);a(e)}catch(e){i(e)}else i(new Error(`Request failed with status ${s.status}`))},s.onerror=()=>{i(new Error("Network error"))},s.ontimeout=()=>{i(new Error("Request timeout"))},n?s.send(n):s.send()})))({url:d,method:"POST",headers:{"Content-Type":"application/json"},data:JSON.stringify(t),withCredentials:!0})},L=(e=!1)=>{const t=T();if(t.length){if(!E&&(t.length>=a||e))return v&&(clearTimeout(v),v=null),A([]),void $(t).then((()=>{E=0})).catch((()=>{console.error("send report fail"),N(t)})).finally((()=>{L()}));if(null===v){v=setTimeout((()=>{const e=T();e.length?y||(A([]),y=$(e).then((()=>{E=0})).catch((()=>{N(e)})).finally((()=>{v=null,y=null,L()}))):v=null}),(E+1)*i)}}},N=e=>{if(E++,E>c)return void(E=0);const t=T();A(t.concat(e))},k=e=>{$([_(n.channelId,e,n.siteId)])},I=e=>{let t=[_(n.channelId,e,n.siteId)];try{const e=T();e&&(t=t.concat(e),A(t));const n=(e=>{const t=JSON.stringify(e);return(new TextEncoder).encode(t).length/1024})(t);L(n>=s)}catch(e){console.error("lazy report fail: ",e)}};return t((()=>{L(!0)})),(e=>{try{h=new WeakMap}catch(e){console.error("create WeakMap fail: ",e)}const t=e=>{if(h?.get(e))return;const t=e.dataset.duration||500;h?.set(e,{duration:t,timer:null}),m?.observe(e)},n=e=>{const t=h?.get(e);t&&(m?.unobserve(e),t?.timer&&clearTimeout(t.timer),h?.delete(e))},r=t=>{t.forEach((t=>{const r=t.target,o=h?.get(r);o&&(o.timer&&(clearTimeout(o.timer),o.timer=null),t.isIntersecting&&(o.timer=window.setTimeout((()=>{const t=r.dataset.eventDetail;r.hasAttribute(w)&&(e({spm:r.dataset.spm,data_type:"behavior",event_type:"view",event_detail:t}),r.removeAttribute(w)),r.hasAttribute(p)?e({spm:r.dataset.spm,data_type:"behavior",event_type:"expose",event_detail:t}):n(r)}),o.duration)))}))};m=(()=>{let e=null;try{e=new IntersectionObserver(r,{root:null,threshold:.5})}catch(e){console.error("create IntersectionObserver fail: ",e)}return e})(),document.querySelectorAll(`[${p}]`).forEach((e=>t(e))),document.querySelectorAll(`[${w}]`).forEach((e=>t(e))),new MutationObserver((e=>{e.forEach((e=>{if("attributes"===e.type&&e.target instanceof HTMLElement){const r=e.target;r.hasAttribute(p)||r.hasAttribute(w)?t(r):n(r)}else"childList"===e.type&&(e.addedNodes.forEach((e=>{e instanceof HTMLElement&&(e.hasAttribute(p)||e.hasAttribute(w)?t(e):(e.querySelectorAll(`[${p}]`).forEach((e=>t(e))),e.querySelectorAll(`[${w}]`).forEach((e=>t(e)))))})),e.removedNodes.forEach((e=>{if(e instanceof HTMLElement){const t=h?.get(e);t?n(e):(e.querySelectorAll(`[${p}]`).forEach((e=>n(e))),e.querySelectorAll(`[${w}]`).forEach((e=>n(e))))}})))}))})).observe(document.body,{attributes:!0,childList:!0,subtree:!0})})(I),!1!==n.behavior&&u(I),window.addEventListener("beforeunload",(()=>{L(!0)})),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState&&L(!0)})),window.addEventListener("pagehide",(()=>{L(!0)})),window.trackMonitor={report:I,realtimeReport:k,bindUser:b,unBindUser:S},{bindUser:b,unBindUser:S,report:I,realtimeReport:k}};export{E as default};
1
+ const e=!!navigator?.sendBeacon,t=new Int32Array(4);class n{static hashStr(e,t=!1){return this.onePassHasher.start().appendStr(e).end(t)}static hashAsciiStr(e,t=!1){return this.onePassHasher.start().appendAsciiStr(e).end(t)}static stateIdentity=new Int32Array([1732584193,-271733879,-1732584194,271733878]);static buffer32Identity=new Int32Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);static hexChars="0123456789abcdef";static hexOut=[];static onePassHasher=new n;static _hex(e){const t=n.hexChars,r=n.hexOut;let o,i,a,s;for(s=0;s<4;s+=1)for(i=8*s,o=e[s],a=0;a<8;a+=2)r[i+1+a]=t.charAt(15&o),o>>>=4,r[i+0+a]=t.charAt(15&o),o>>>=4;return r.join("")}static _md5cycle(e,t){let n=e[0],r=e[1],o=e[2],i=e[3];n+=(r&o|~r&i)+t[0]-680876936|0,n=(n<<7|n>>>25)+r|0,i+=(n&r|~n&o)+t[1]-389564586|0,i=(i<<12|i>>>20)+n|0,o+=(i&n|~i&r)+t[2]+606105819|0,o=(o<<17|o>>>15)+i|0,r+=(o&i|~o&n)+t[3]-1044525330|0,r=(r<<22|r>>>10)+o|0,n+=(r&o|~r&i)+t[4]-176418897|0,n=(n<<7|n>>>25)+r|0,i+=(n&r|~n&o)+t[5]+1200080426|0,i=(i<<12|i>>>20)+n|0,o+=(i&n|~i&r)+t[6]-1473231341|0,o=(o<<17|o>>>15)+i|0,r+=(o&i|~o&n)+t[7]-45705983|0,r=(r<<22|r>>>10)+o|0,n+=(r&o|~r&i)+t[8]+1770035416|0,n=(n<<7|n>>>25)+r|0,i+=(n&r|~n&o)+t[9]-1958414417|0,i=(i<<12|i>>>20)+n|0,o+=(i&n|~i&r)+t[10]-42063|0,o=(o<<17|o>>>15)+i|0,r+=(o&i|~o&n)+t[11]-1990404162|0,r=(r<<22|r>>>10)+o|0,n+=(r&o|~r&i)+t[12]+1804603682|0,n=(n<<7|n>>>25)+r|0,i+=(n&r|~n&o)+t[13]-40341101|0,i=(i<<12|i>>>20)+n|0,o+=(i&n|~i&r)+t[14]-1502002290|0,o=(o<<17|o>>>15)+i|0,r+=(o&i|~o&n)+t[15]+1236535329|0,r=(r<<22|r>>>10)+o|0,n+=(r&i|o&~i)+t[1]-165796510|0,n=(n<<5|n>>>27)+r|0,i+=(n&o|r&~o)+t[6]-1069501632|0,i=(i<<9|i>>>23)+n|0,o+=(i&r|n&~r)+t[11]+643717713|0,o=(o<<14|o>>>18)+i|0,r+=(o&n|i&~n)+t[0]-373897302|0,r=(r<<20|r>>>12)+o|0,n+=(r&i|o&~i)+t[5]-701558691|0,n=(n<<5|n>>>27)+r|0,i+=(n&o|r&~o)+t[10]+38016083|0,i=(i<<9|i>>>23)+n|0,o+=(i&r|n&~r)+t[15]-660478335|0,o=(o<<14|o>>>18)+i|0,r+=(o&n|i&~n)+t[4]-405537848|0,r=(r<<20|r>>>12)+o|0,n+=(r&i|o&~i)+t[9]+568446438|0,n=(n<<5|n>>>27)+r|0,i+=(n&o|r&~o)+t[14]-1019803690|0,i=(i<<9|i>>>23)+n|0,o+=(i&r|n&~r)+t[3]-187363961|0,o=(o<<14|o>>>18)+i|0,r+=(o&n|i&~n)+t[8]+1163531501|0,r=(r<<20|r>>>12)+o|0,n+=(r&i|o&~i)+t[13]-1444681467|0,n=(n<<5|n>>>27)+r|0,i+=(n&o|r&~o)+t[2]-51403784|0,i=(i<<9|i>>>23)+n|0,o+=(i&r|n&~r)+t[7]+1735328473|0,o=(o<<14|o>>>18)+i|0,r+=(o&n|i&~n)+t[12]-1926607734|0,r=(r<<20|r>>>12)+o|0,n+=(r^o^i)+t[5]-378558|0,n=(n<<4|n>>>28)+r|0,i+=(n^r^o)+t[8]-2022574463|0,i=(i<<11|i>>>21)+n|0,o+=(i^n^r)+t[11]+1839030562|0,o=(o<<16|o>>>16)+i|0,r+=(o^i^n)+t[14]-35309556|0,r=(r<<23|r>>>9)+o|0,n+=(r^o^i)+t[1]-1530992060|0,n=(n<<4|n>>>28)+r|0,i+=(n^r^o)+t[4]+1272893353|0,i=(i<<11|i>>>21)+n|0,o+=(i^n^r)+t[7]-155497632|0,o=(o<<16|o>>>16)+i|0,r+=(o^i^n)+t[10]-1094730640|0,r=(r<<23|r>>>9)+o|0,n+=(r^o^i)+t[13]+681279174|0,n=(n<<4|n>>>28)+r|0,i+=(n^r^o)+t[0]-358537222|0,i=(i<<11|i>>>21)+n|0,o+=(i^n^r)+t[3]-722521979|0,o=(o<<16|o>>>16)+i|0,r+=(o^i^n)+t[6]+76029189|0,r=(r<<23|r>>>9)+o|0,n+=(r^o^i)+t[9]-640364487|0,n=(n<<4|n>>>28)+r|0,i+=(n^r^o)+t[12]-421815835|0,i=(i<<11|i>>>21)+n|0,o+=(i^n^r)+t[15]+530742520|0,o=(o<<16|o>>>16)+i|0,r+=(o^i^n)+t[2]-995338651|0,r=(r<<23|r>>>9)+o|0,n+=(o^(r|~i))+t[0]-198630844|0,n=(n<<6|n>>>26)+r|0,i+=(r^(n|~o))+t[7]+1126891415|0,i=(i<<10|i>>>22)+n|0,o+=(n^(i|~r))+t[14]-1416354905|0,o=(o<<15|o>>>17)+i|0,r+=(i^(o|~n))+t[5]-57434055|0,r=(r<<21|r>>>11)+o|0,n+=(o^(r|~i))+t[12]+1700485571|0,n=(n<<6|n>>>26)+r|0,i+=(r^(n|~o))+t[3]-1894986606|0,i=(i<<10|i>>>22)+n|0,o+=(n^(i|~r))+t[10]-1051523|0,o=(o<<15|o>>>17)+i|0,r+=(i^(o|~n))+t[1]-2054922799|0,r=(r<<21|r>>>11)+o|0,n+=(o^(r|~i))+t[8]+1873313359|0,n=(n<<6|n>>>26)+r|0,i+=(r^(n|~o))+t[15]-30611744|0,i=(i<<10|i>>>22)+n|0,o+=(n^(i|~r))+t[6]-1560198380|0,o=(o<<15|o>>>17)+i|0,r+=(i^(o|~n))+t[13]+1309151649|0,r=(r<<21|r>>>11)+o|0,n+=(o^(r|~i))+t[4]-145523070|0,n=(n<<6|n>>>26)+r|0,i+=(r^(n|~o))+t[11]-1120210379|0,i=(i<<10|i>>>22)+n|0,o+=(n^(i|~r))+t[2]+718787259|0,o=(o<<15|o>>>17)+i|0,r+=(i^(o|~n))+t[9]-343485551|0,r=(r<<21|r>>>11)+o|0,e[0]=n+e[0]|0,e[1]=r+e[1]|0,e[2]=o+e[2]|0,e[3]=i+e[3]|0}_dataLength=0;_bufferLength=0;_state=new Int32Array(4);_buffer=new ArrayBuffer(68);_buffer8;_buffer32;constructor(){this._buffer8=new Uint8Array(this._buffer,0,68),this._buffer32=new Uint32Array(this._buffer,0,17),this.start()}start(){return this._dataLength=0,this._bufferLength=0,this._state.set(n.stateIdentity),this}appendStr(e){const t=this._buffer8,r=this._buffer32;let o,i,a=this._bufferLength;for(i=0;i<e.length;i+=1){if(o=e.charCodeAt(i),o<128)t[a++]=o;else if(o<2048)t[a++]=192+(o>>>6),t[a++]=63&o|128;else if(o<55296||o>56319)t[a++]=224+(o>>>12),t[a++]=o>>>6&63|128,t[a++]=63&o|128;else{if(o=1024*(o-55296)+(e.charCodeAt(++i)-56320)+65536,o>1114111)throw new Error("Unicode standard supports code points up to U+10FFFF");t[a++]=240+(o>>>18),t[a++]=o>>>12&63|128,t[a++]=o>>>6&63|128,t[a++]=63&o|128}a>=64&&(this._dataLength+=64,n._md5cycle(this._state,r),a-=64,r[0]=r[16])}return this._bufferLength=a,this}appendAsciiStr(e){const t=this._buffer8,r=this._buffer32;let o,i=this._bufferLength,a=0;for(;;){for(o=Math.min(e.length-a,64-i);o--;)t[i++]=e.charCodeAt(a++);if(i<64)break;this._dataLength+=64,n._md5cycle(this._state,r),i=0}return this._bufferLength=i,this}appendByteArray(e){const t=this._buffer8,r=this._buffer32;let o,i=this._bufferLength,a=0;for(;;){for(o=Math.min(e.length-a,64-i);o--;)t[i++]=e[a++];if(i<64)break;this._dataLength+=64,n._md5cycle(this._state,r),i=0}return this._bufferLength=i,this}getState(){const e=this._state;return{buffer:String.fromCharCode.apply(null,Array.from(this._buffer8)),buflen:this._bufferLength,length:this._dataLength,state:[e[0],e[1],e[2],e[3]]}}setState(e){const t=e.buffer,n=e.state,r=this._state;let o;for(this._dataLength=e.length,this._bufferLength=e.buflen,r[0]=n[0],r[1]=n[1],r[2]=n[2],r[3]=n[3],o=0;o<t.length;o+=1)this._buffer8[o]=t.charCodeAt(o)}end(e=!1){const r=this._bufferLength,o=this._buffer8,i=this._buffer32,a=1+(r>>2);this._dataLength+=r;const s=8*this._dataLength;if(o[r]=128,o[r+1]=o[r+2]=o[r+3]=0,i.set(n.buffer32Identity.subarray(a),a),r>55&&(n._md5cycle(this._state,i),i.set(n.buffer32Identity)),s<=4294967295)i[14]=s;else{const n=s.toString(16).match(/(.*?)(.{0,8})$/);if(null===n)return e?t:"";const r=parseInt(n[2],16),o=parseInt(n[1],16)||0;i[14]=r,i[15]=o}return n._md5cycle(this._state,i),e?this._state:n._hex(this._state)}}if("5d41402abc4b2a76b9719d911017c592"!==n.hashStr("hello"))throw new Error("Md5 self test failed.");const r=window.requestIdleCallback||window.requestAnimationFrame||(e=>setTimeout(e,17));function o(e,t=150,n=!1){let r=null;return function(...o){const i=this,a=n&&!r;r&&clearTimeout(r),r=setTimeout((()=>{r=null,n||e.apply(i,o)}),t),a&&e.apply(i,o)}}const i=(e,t=300)=>{let n=0;return function(...r){const o=Date.now();o-n>=t&&(n=o,e.apply(this,r))}};function a(e,t=""){if(!e)return t;const n=e.parentElement,{id:r}=e,o=e.tagName.toLowerCase(),i=t?`>${t}`:"";return n&&n!==document.documentElement&&n!==document.body?r?`#${r}${i}`:a(n,`${o}${i}`):`${o}${i}`}const s=()=>{if(window.performance?.navigation)return performance.navigation.type;if(window.performance?.getEntriesByType){const e=performance.getEntriesByType("navigation");if(e.length>0)return e[0].type}return 255},c=e=>{"prerendering"in document&&document.prerendering?(e=>{"prerendering"in document&&document.prerendering?addEventListener("prerenderingchange",(()=>e()),!0):e()})((()=>c(e))):"complete"!==document?.readyState?addEventListener("load",(()=>c(e)),!0):setTimeout(e)};function l(e){return"number"!=typeof e||!isFinite(e)||e<0?null:Math.round(100*e)/100}const d=Array(32);const u=e=>e instanceof ErrorEvent?"Script error."===e.message?"cors":"js":"resource",m=e=>n.hashStr(e);const p={view:"#3b82f6",click:"#06b6d4",expose:"#8b5cf6",enter:"#10b981",leave:"#f59e0b",stay:"#84cc16",cart:"#ec4899",buy:"#ef4444",pay:"#dc2626",default:"#6b7280"},f={view:"👁️",click:"👆",expose:"✨",enter:"🚪",leave:"👋",stay:"⏱️",cart:"🛒",buy:"💰",pay:"💳",default:"📊"},h={common:"#3b82f6",behavior:"#10b981",performance:"#f59e0b",error:"#ef4444",custom:"#8b5cf6",default:"#6b7280"},g=(e,t)=>{t.forEach(((t,n)=>{const r=t.event_type||"unknown",o=t.data_type||"common",i=(e=>p[e]||p.default)(r),a=(e=>h[e]||h.default)(o),s=(e=>f[e]||f.default)(r);let c=t.event_detail;if("string"==typeof c)try{c=JSON.parse(c)}catch(e){}console.groupCollapsed(`%c${s} [TM-${e}] %c${o.toUpperCase()}%c → %c${r.toUpperCase()}%c #${n+1}`,"color: #6b7280; font-weight: bold;",`color: ${a}; font-weight: bold; background: ${a}20; padding: 2px 6px; border-radius: 3px;`,"color: #6b7280;",`color: ${i}; font-weight: bold; background: ${i}20; padding: 2px 6px; border-radius: 3px;`,"color: #6b7280; font-weight: normal;");const l={...t,event_detail:c};console.log("%c"+JSON.stringify(l,null,2),"color: #6b7280; font-family: monospace; font-size: 11px; line-height: 1.5;"),console.groupEnd()})),console.log(`%c✅ [TM] 本次通过 ${e} 上报 ${t.length} 条埋点数据`,"color: #10b981; font-weight: bold; font-size: 12px; padding: 4px 8px; background: #10b98120; border-radius: 4px; border-left: 3px solid #10b981;")};let y;const v="TRACK_MONITOR_DATA",w="MONITOR_REAL_TIME_DATA",T="TRACK_MONITOR_USER",b="TRACK_MONITOR_LOGGER",_={timer:null,promise:null},E={timer:null,promise:null},S=e=>{const t=JSON.stringify(e);return(new TextEncoder).encode(t).length/1024},L=t=>{y={accessKey:t.accessKey,channelId:t.channelId,siteId:t.siteId,url:t.url||"http://api.mossego.com/v1/push/event",realTimeUrl:t.realTimeUrl||"http://api.mossego.com/v1/push/real-time-event",cacheNumber:t.cacheNumber||30,reportInterval:t.reportInterval||3e4,realTimeReportInterval:t.realTimeReportInterval||200,maxCacheSize:t.maxCacheSize||57344,maxRetries:t.maxRetries||10,isLogger:!!t.isLogger,errorTraceRate:t.errorTraceRate||.5,traceBehavior:t.traceBehavior??!0,tracePerformance:t.tracePerformance??!0,traceError:t.traceError??!0};let{url:n,realTimeUrl:o,cacheNumber:i,reportInterval:a,realTimeReportInterval:s,maxCacheSize:c,maxRetries:l}=y,d=0;const u=e=>{try{localStorage.setItem(T,e)}catch(e){console.error("[TM]: monitor bind user fail: ",e)}},m=()=>{localStorage.removeItem(T)},p=e=>{let t=[];try{t=JSON.parse(localStorage.getItem(e)||"[]")}catch(e){console.error("[TM]: get monitor data fail: ",e)}return t},f=(e,t)=>{try{localStorage.setItem(e,JSON.stringify(t))}catch(n){console.error("[TM]: save monitor data error: ",t),localStorage.setItem(e,"[]")}},h=(t,r)=>{let i=t?o:n;if(i=i.includes("?")?`${i}&accessKey=${y?.accessKey}`:`${i}?accessKey=${y?.accessKey}`,e){const e=((e,t)=>navigator.sendBeacon(e,t))(i,new Blob([JSON.stringify({data:r})],{type:"application/json"}));if(e)return y?.isLogger&&g("SendBeacon",r),Promise.resolve()}return y?.isLogger&&g("XHR",r),(({method:e,url:t,data:n,headers:r={},withCredentials:o=!1})=>new Promise(((i,a)=>{const s=new XMLHttpRequest;s.open(e,t,!0),Object.keys(r).forEach((e=>{s.setRequestHeader(e,r[e])})),s.withCredentials=!!o,s.onreadystatechange=()=>{if(4===s.readyState)if(s.status>=200&&s.status<300)try{const e=JSON.parse(s.responseText);i(e)}catch(e){a(e)}else a(new Error(`[TM]: Request failed with status ${s.status}`))},s.onerror=()=>{a(new Error("[TM]: Network error"))},s.ontimeout=()=>{a(new Error("[TM]: Request timeout"))},n?s.send(n):s.send()})))({url:i,method:"POST",headers:{"Content-Type":"application/json"},data:JSON.stringify({data:r}),withCredentials:!0})},L=(e,t=!1)=>{const n=p(e);if(!n.length)return;const r=(e=>e===w)(e),o=r?E:_;if(!d&&(n.length>=i||t))return null!==o.timer&&(clearTimeout(o.timer),o.timer=null),f(e,[]),void h(r,n).then((()=>{d=0})).catch((()=>{console.error("[TM]: send report fail, retryCount: ",d),C(e,n)})).finally((()=>{L(e)}));if(null===o.timer){const t=(d+1)*(r?s:a);o.timer=setTimeout((()=>{const t=p(e);t.length?o.promise||(f(e,[]),o.promise=h(r,t).then((()=>{d=0})).catch((()=>{C(e,t)})).finally((()=>{o.timer=null,o.promise=null,L(e)}))):o.timer=null}),t)}},C=(e,t)=>{if(d++,d>l)return void(d=0);const n=p(e);f(e,n.concat(t))},A=e=>{if(!e||"object"!=typeof e)return void console.error("[TM]: report data must be an object");const t=!0===e.track_real_time,n=(e=>({session_id:e.session_id,request_id:e.request_id,spm:e.spm,data_type:e.data_type||"behavior",event_type:e.event_type,event_detail:"string"==typeof e.event_detail?e.event_detail:JSON.stringify(e.event_detail),page_url:location.href,os:window.navigator.platform,user_id:localStorage.getItem(T)||void 0,user_agent:window.navigator.userAgent,screen_width:window.screen.width,screen_height:window.screen.height,lib_version:"1.1.1",lib_type:"js",event_time:(new Date).getTime().toString(),timezone_offset:(new Date).getTimezoneOffset().toString(),site_id:y?.siteId,channel_id:y?.channelId}))(e);try{if(t){let e=[n];const t=p(w);t&&(e=e.concat(t)),f(w,e);const r=S(e);L(w,r>=c)}let e=[n];const r=p(v);r&&(e=e.concat(r)),f(v,e);const o=S(e);L(v,o>=c)}catch(e){console.error("[TM]: report fail: ",e)}},I=()=>{y.isLogger=!0;try{localStorage.setItem(b,"true")}catch(e){console.error("[TM]: enable logger fail:",e)}},M=()=>{y.isLogger=!1;try{localStorage.setItem(b,"false")}catch(e){console.error("[TM]: disable logger fail:",e)}};return r((()=>{L(v,!0),L(w,!0)})),window.trackMonitor={report:A,bindUser:u,unBindUser:m,enableLogger:I,disableLogger:M},{client:{report:A,bindUser:u,unBindUser:m,enableLogger:I,disableLogger:M},beforeClose:()=>{window.addEventListener("beforeunload",(()=>{L(v,!0),L(w,!0)}))}}},C=(A=16,function(){for(let e=0;e<2*A;e++)d[e]=Math.floor(16*Math.random())+48,d[e]>=58&&(d[e]+=39);return String.fromCharCode.apply(null,d.slice(0,2*A))})();var A;const I=e=>{const t=history[e];return function(){const n=t.apply(this,arguments),r=new Event(e);return window.dispatchEvent(r),n}},M=e=>{window.addEventListener("replaceState",(t=>e(t)),!0),window.addEventListener("pushState",(t=>e(t)),!0)},x=e=>{window.addEventListener("popstate",(t=>e(t)),!0)},k=()=>{history.pushState=I("pushState"),history.replaceState=I("replaceState"),(()=>{let e="";const t=()=>{const t=window.location.href;if(t===e)return;const{host:n,hostname:r,href:o,protocol:i,origin:a,port:c,pathname:l,search:d,hash:u}=window.location,m={host:n,hostname:r,href:o,protocol:i,origin:a,port:c,pathname:l,search:d,hash:u,title:document.title,language:navigator.language.substring(0,2),user_agent:navigator.userAgent,win_screen:`${window.screen.width}x${window.screen.height}`,doc_screen:`${document.documentElement.clientWidth}x${document.documentElement.clientHeight}`,referrer:document.referrer,type:s()};window.trackMonitor.report({data_type:"common",event_type:"page_view",event_detail:m}),e=t},n=o(t,200);t(),x((()=>{n()})),M((()=>{n()}))})(),(()=>{let e=document.referrer,t=window.location.href,n=Date.now(),r=!0;const i=(r=!1)=>{if(window.location.href!==t||r){const r=Date.now()-n;r>200&&window.trackMonitor.report({data_type:"common",event_type:"page_leave",event_detail:{url:t,referrer:e,duration:r}}),n=Date.now(),e=t,t=window.location.href}},a=o(i);i(),x((()=>{a()})),M((()=>{a()})),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState?r&&(r=!1,i(!0)):(r=!0,n=Date.now())})),window.addEventListener("beforeunload",(()=>{r&&(r=!1,i(!0))}),!0)})(),(()=>{const e=i((e=>{const t=function(e){if(!e)return;if(["A","INPUT","TEXTAREA","BUTTON"].includes(e.tagName))return e;if(e.hasAttribute("track-click"))return e;return e.closest("a, button, [track-click]")||void 0}(e.target);if(!t)return;const n={element_id:t.id,element_content:t.textContent?.trim()||null,element_class_name:t.className||null,element_name:t.getAttribute("name")||null,element_type:t.tagName.toLowerCase(),element_path:a(t),scroll_width:document.documentElement.scrollWidth,scroll_height:document.documentElement.scrollHeight,pageX:e.pageX,pageY:e.pageY,ratio:window.devicePixelRatio||1};window.trackMonitor.report({data_type:"common",event_type:"click",event_detail:n})}));window.addEventListener("click",e,!0)})()};let R=null,$=null;const q="track-expose",N="track-view",P=e=>{try{$=new WeakMap}catch(e){console.error("[TM]: create WeakMap fail: ",e)}const t=(e,t=!1)=>{const r=$?.get(e);if(r&&!t)return;r&&(r.viewTimer&&clearTimeout(r.viewTimer),r.exposeTimer&&clearTimeout(r.exposeTimer));const o=e.dataset.durationView||500,i=e.dataset.durationExpose||500;$?.set(e,{duration_view:o,duration_expose:i,viewTimer:null,exposeTimer:null}),R?.observe(e),t&&function(e){if(!(e instanceof Element))return!1;if(!function e(t){if(!t)return!0;const n=window.getComputedStyle(t);return"none"!==n.display&&"hidden"!==n.visibility&&0!==parseFloat(n.opacity)&&e(t.parentElement)}(e))return!1;const t=e.getBoundingClientRect();return!(t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth))}(e)&&n(e)},n=t=>{const n=$?.get(t);if(!n)return;const o=t.dataset.eventDetail,i=t.dataset.traceid??void 0,a=t.dataset.spm,s=t.hasAttribute("track-real-time"),c=t.hasAttribute(N),l=t.hasAttribute(q);c&&l?n.exposeTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"common",event_type:"view_expose",event_detail:o,track_real_time:s}),t.removeAttribute(N),n.exposeTimer=null}),parseInt(n.duration_expose,10)):(c&&(n.viewTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"common",event_type:"view",event_detail:o,track_real_time:s}),t.removeAttribute(N),l&&n.exposeTimer||r(t),n.viewTimer=null}),parseInt(n.duration_view,10))),l&&(n.exposeTimer=window.setTimeout((()=>{e({spm:a,request_id:i,data_type:"common",event_type:"expose",event_detail:o,track_real_time:s}),n.exposeTimer=null}),parseInt(n.duration_expose,10))))},r=e=>{const t=$?.get(e);t&&(R?.unobserve(e),t.viewTimer&&clearTimeout(t.viewTimer),t.exposeTimer&&clearTimeout(t.exposeTimer),$?.delete(e))},o=e=>{e.forEach((e=>{const t=e.target,o=$?.get(t);o&&(o.viewTimer&&(clearTimeout(o.viewTimer),o.viewTimer=null),o.exposeTimer&&(clearTimeout(o.exposeTimer),o.exposeTimer=null),e.isIntersecting&&(n(t),t.hasAttribute(N)||t.hasAttribute(q)||r(t)))}))};R=(()=>{let e=null;try{e=new IntersectionObserver(o,{root:null,threshold:.5})}catch(e){console.error("[TM]: create IntersectionObserver fail: ",e)}return e})();new Set([...document.querySelectorAll(`[${q}]`),...document.querySelectorAll(`[${N}]`)]).forEach((e=>t(e))),new MutationObserver((e=>{e.forEach((e=>{if("attributes"===e.type&&e.target instanceof HTMLElement){const n=e.target,o=e.attributeName,i=["data-event-detail","data-traceid","data-spm","data-duration-view","data-duration-expose"];n.hasAttribute(q)||n.hasAttribute(N)?i.includes(o)?t(n,!0):o!==q&&o!==N||t(n,!1):r(n)}else"childList"===e.type&&(e.addedNodes.forEach((e=>{if(e instanceof HTMLElement)if(e.hasAttribute(q)||e.hasAttribute(N))t(e);else{new Set([...e.querySelectorAll(`[${q}]`),...e.querySelectorAll(`[${N}]`)]).forEach((e=>t(e)))}})),e.removedNodes.forEach((e=>{if(e instanceof HTMLElement){const t=$?.get(e);if(t)r(e);else{new Set([...e.querySelectorAll(`[${q}]`),...e.querySelectorAll(`[${N}]`)]).forEach((e=>r(e)))}}})))}))})).observe(document.body,{attributes:!0,childList:!0,subtree:!0})},B=/^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;function O(e){const t=e.match(B);if(!t)return{};return{filename:t[2],functionName:t[1]||"",lineno:parseInt(t[3],10)||void 0,colno:parseInt(t[4],10)||void 0}}function H(e){try{const{stack:t}=e;if(!t)return[];const n=[];for(const e of t.split("\n").slice(1)){const t=O(e);!t||t.filename?.includes("chrome-extension://")||t.filename?.includes("node_modules")||t.filename?.includes("<anonymous>")||n.push(t)}return n.slice(0,10)}catch(e){return[]}}const F=[],z=(e,t)=>{var n;((n=y?.errorTraceRate??.5)<0||n>1?(console.warn("[TM]: probability should be between 0 and 1"),0):Math.random()<n)&&(window.trackMonitor.report(t),F.push(e))},U=()=>{window.addEventListener("error",(e=>{(e=>{if("js"!==u(e))return;if((e=>{const t=e.error?.stack||"";return/chrome-extension:\/\//.test(t)})(e))return;const t=m(`js-${e.message}-${e.filename}`);if(F.includes(t))return;const n=H(e.error),r={traceId:C,msg:e.message,target:n[0]?`${n[0].filename?.split("?")[0]}:${n[0].lineno}:${n[0].colno}`:"",stack:n,errorUuid:t,meta:{filename:e.filename,colno:e.colno,lineno:e.lineno}};z(t,{data_type:"error",event_type:"js",event_detail:r})})(e)}),!0)},D=()=>{window.addEventListener("error",(e=>{(e=>{if("resource"!==u(e))return;const t=e.target,n=m(`resource-${t.src}-${t.tagName}`);if(F.includes(n))return;const r={traceId:C,msg:`加载${t.tagName}失败`,target:t.src?.split("?")[0],errorUuid:n,meta:{url:t.src,html:t.outerHTML,tagName:t.tagName}};z(n,{data_type:"error",event_type:"resource",event_detail:r})})(e)}),!0)},j=()=>{window.addEventListener("unhandledrejection",(e=>(e=>{const t=e.reason?.message||e.reason,n=m(`unhandledrejection-${t}`);if(F.includes(n))return;const r={traceId:C,msg:t,stack:H(e.reason),errorUuid:n};z(n,{data_type:"error",event_type:"unhandledrejection",event_detail:r})})(e)),!0)},K=()=>{const e=(e,t,n)=>{if(t){const r=m(`http-${t}-${e.url}-${n}`);if(F.includes(r))return;const o={traceId:C,errorType:t,msg:n,target:e.url.split("?")[0],errorUuid:r,request:e};z(r,{data_type:"error",event_type:"http",event_detail:o})}else if(e.status>=400){let n=e.statusText;const r=m(`http-${t="http_error"}-${e.url}-${n}`);if(F.includes(r))return;const o={traceId:C,errorUuid:r,errorType:t,target:e.url.split("?")[0],msg:n,request:e};z(r,{data_type:"error",event_type:"http",event_detail:o})}};((e,t)=>{if("XMLHttpRequest"in window&&"function"==typeof window.XMLHttpRequest){const e=window.XMLHttpRequest;window.oXMLHttpRequest||(window.oXMLHttpRequest=e),window.XMLHttpRequest=function(){const n=new e,{open:r,send:o}=n;let i={};n.open=(e,t,o,a,s)=>{void 0===o&&(o=!0),i.method=e,i.url=t,r.call(n,e,t,o,a,s)},n.send=e=>{i.requestTime=(new Date).getTime(),o.call(n,e)};const a=(e,r)=>{const{status:o,statusText:a}=n,s=(new Date).getTime();i={...i,status:o,statusText:a,responseTime:s,duration:s-i.requestTime},"function"==typeof t&&t(i,e,r)};return n.addEventListener("loadend",(()=>a())),n.addEventListener("error",(()=>a("net_error","ERR_NETWORK"))),n.addEventListener("abort",(()=>a("cannel_request","ERR_CANCELED"))),n.addEventListener("timeout",(()=>a("timeout","ERR_NETWORK"))),n}}})(0,e),((e,t)=>{if("fetch"in window&&"function"==typeof window.fetch){const e=window.fetch;window.oFetch||(window.oFetch=e),window.fetch=async(n,r)=>{let o={};return o.method=r?.method||"",o.url=(n&&"string"!=typeof n?n?.url:n)||"",o.requestTime=(new Date).getTime(),e.call(window,n,r).then((async e=>{if("function"==typeof t){const n=e.clone(),r=(new Date).getTime();o={...o,status:n.status,statusText:n.statusText,responseTime:r,duration:r-o.requestTime},t(o)}return e})).catch((e=>{if("function"==typeof t){const n=(new Date).getTime();o={...o,responseTime:n,duration:n-o.requestTime},"AbortError"===e.name?t(o,"cannel_request","ERR_CANCELED"):t(o,"net_error","ERR_NETWORK")}return Promise.reject(e)}))}}})(0,e)};let X=-1;const W=e=>{addEventListener("pageshow",(t=>{t.persisted&&(X=t.timeStamp,e(t))}),!0)},J=(e,t,n,r)=>{let o,i;return a=>{t.value>=0&&(a||r)&&(i=t.value-(o??0),(i||void 0===o)&&(o=t.value,t.delta=i,t.rating=((e,t)=>e>t[1]?"poor":e>t[0]?"needs-improvement":"good")(t.value,n),e(t)))}},G=e=>{requestAnimationFrame((()=>requestAnimationFrame((()=>e()))))},V=()=>{const e=performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},Y=()=>{const e=V();return e?.activationStart??0},Q=(e,t=-1)=>{const n=V();let r="navigate";return X>=0?r="back-forward-cache":n&&(document.prerendering||Y()>0?r="prerender":document.wasDiscarded?r="restore":n.type&&(r=n.type.replace(/_/g,"-"))),{name:e,value:t,rating:"good",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:r}},Z=new WeakMap;function ee(e,t){return Z.get(e)||Z.set(e,new t),Z.get(e)}class te{t;i=0;o=[];h(e){if(e.hadRecentInput)return;const t=this.o[0],n=this.o.at(-1);this.i&&t&&n&&e.startTime-n.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e)}}const ne=(e,t,n={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(e)){const r=new PerformanceObserver((e=>{Promise.resolve().then((()=>{t(e.getEntries())}))}));return r.observe({type:e,buffered:!0,...n}),r}}catch{}},re=e=>{let t=!1;return()=>{t||(e(),t=!0)}};let oe=-1;const ie=new Set,ae=()=>"hidden"!==document.visibilityState||document.prerendering?1/0:0,se=e=>{if("hidden"===document.visibilityState){if("visibilitychange"===e.type)for(const e of ie)e();isFinite(oe)||(oe="visibilitychange"===e.type?e.timeStamp:0,removeEventListener("prerenderingchange",se,!0))}},ce=()=>{if(oe<0){const e=Y(),t=document.prerendering?void 0:globalThis.performance.getEntriesByType("visibility-state").filter((t=>"hidden"===t.name&&t.startTime>e))[0]?.startTime;oe=t??ae(),addEventListener("visibilitychange",se,!0),addEventListener("prerenderingchange",se,!0),W((()=>{setTimeout((()=>{oe=ae()}))}))}return{get firstHiddenTime(){return oe},onHidden(e){ie.add(e)}}},le=e=>{document.prerendering?addEventListener("prerenderingchange",(()=>e()),!0):e()},de=[1800,3e3],ue=(e,t={})=>{le((()=>{const n=ce();let r,o=Q("FCP");const i=ne("paint",(e=>{for(const t of e)"first-contentful-paint"===t.name&&(i.disconnect(),t.startTime<n.firstHiddenTime&&(o.value=Math.max(t.startTime-Y(),0),o.entries.push(t),r(!0)))}));i&&(r=J(e,o,de,t.reportAllChanges),W((n=>{o=Q("FCP"),r=J(e,o,de,t.reportAllChanges),G((()=>{o.value=performance.now()-n.timeStamp,r(!0)}))})))}))},me=[.1,.25];let pe=0,fe=1/0,he=0;const ge=e=>{for(const t of e)t.interactionId&&(fe=Math.min(fe,t.interactionId),he=Math.max(he,t.interactionId),pe=he?(he-fe)/7+1:0)};let ye;const ve=()=>ye?pe:performance.interactionCount??0;let we=0;class Te{u=[];l=new Map;m;p;v(){we=ve(),this.u.length=0,this.l.clear()}L(){const e=Math.min(this.u.length-1,Math.floor((ve()-we)/50));return this.u[e]}h(e){if(this.m?.(e),!e.interactionId&&"first-input"!==e.entryType)return;const t=this.u.at(-1);let n=this.l.get(e.interactionId);if(n||this.u.length<10||e.duration>t.P){if(n?e.duration>n.P?(n.entries=[e],n.P=e.duration):e.duration===n.P&&e.startTime===n.entries[0].startTime&&n.entries.push(e):(n={id:e.interactionId,entries:[e],P:e.duration},this.l.set(n.id,n),this.u.push(n)),this.u.sort(((e,t)=>t.P-e.P)),this.u.length>10){const e=this.u.splice(10);for(const t of e)this.l.delete(t.id)}this.p?.(n)}}}const be=e=>{const t=globalThis.requestIdleCallback||setTimeout;"hidden"===document.visibilityState?e():(e=re(e),addEventListener("visibilitychange",e,{once:!0,capture:!0}),t((()=>{e(),removeEventListener("visibilitychange",e,{capture:!0})})))},_e=[200,500],Ee=(e,t={})=>{if(!globalThis.PerformanceEventTiming||!("interactionId"in PerformanceEventTiming.prototype))return;const n=ce();le((()=>{"interactionCount"in performance||ye||(ye=ne("event",ge,{type:"event",buffered:!0,durationThreshold:0}));let r,o=Q("INP");const i=ee(t,Te),a=e=>{be((()=>{for(const t of e)i.h(t);const t=i.L();t&&t.P!==o.value&&(o.value=t.P,o.entries=t.entries,r())}))},s=ne("event",a,{durationThreshold:t.durationThreshold??40});r=J(e,o,_e,t.reportAllChanges),s&&(s.observe({type:"first-input",buffered:!0}),n.onHidden((()=>{a(s.takeRecords()),r(!0)})),W((()=>{i.v(),o=Q("INP"),r=J(e,o,_e,t.reportAllChanges)})))}))};class Se{m;h(e){this.m?.(e)}}const Le=[2500,4e3],Ce=[800,1800],Ae=e=>{document.prerendering?le((()=>Ae(e))):"complete"!==document.readyState?addEventListener("load",(()=>Ae(e)),!0):setTimeout(e)};function Ie(){const e={ttfb:null,lcp:null,fp:null,fcp:null,connectionRtt:null,ttfbRequestTime:null,inp:null,cls:null,dcl:null,loadTime:null};((e,t={})=>{le((()=>{const n=ce();let r,o=Q("LCP");const i=ee(t,Se),a=e=>{t.reportAllChanges||(e=e.slice(-1));for(const t of e)i.h(t),t.startTime<n.firstHiddenTime&&(o.value=Math.max(t.startTime-Y(),0),o.entries=[t],r())},s=ne("largest-contentful-paint",a);if(s){r=J(e,o,Le,t.reportAllChanges);const n=re((()=>{a(s.takeRecords()),s.disconnect(),r(!0)})),i=e=>{e.isTrusted&&(be(n),removeEventListener(e.type,i,{capture:!0}))};for(const e of["keydown","click","visibilitychange"])addEventListener(e,i,{capture:!0});W((n=>{o=Q("LCP"),r=J(e,o,Le,t.reportAllChanges),G((()=>{o.value=performance.now()-n.timeStamp,r(!0)}))}))}}))})((t=>{e.lcp=l(t.value)}),{reportAllChanges:!0}),((e,t={})=>{const n=ce();ue(re((()=>{let r,o=Q("CLS",0);const i=ee(t,te),a=e=>{for(const t of e)i.h(t);i.i>o.value&&(o.value=i.i,o.entries=i.o,r())},s=ne("layout-shift",a);s&&(r=J(e,o,me,t.reportAllChanges),n.onHidden((()=>{a(s.takeRecords()),r(!0)})),W((()=>{i.i=0,o=Q("CLS",0),r=J(e,o,me,t.reportAllChanges),G((()=>r()))})),setTimeout(r))})))})((t=>{e.cls=Math.round(1e4*t.value)/1e4}),{reportAllChanges:!0}),Ee((t=>{e.inp=l(t.value)}),{reportAllChanges:!0}),((e,t={})=>{let n=Q("TTFB"),r=J(e,n,Ce,t.reportAllChanges);Ae((()=>{const o=V();o&&(n.value=Math.max(o.responseStart-Y(),0),n.entries=[o],r(!0),W((()=>{n=Q("TTFB",0),r=J(e,n,Ce,t.reportAllChanges),r(!0)})))}))})((t=>{e.ttfb=l(t.value)})),ue((t=>{e.fcp=l(t.value)}));window.addEventListener("beforeunload",(()=>{(()=>{try{performance.getEntriesByType("paint").forEach((t=>{"first-paint"===t.name&&(e.fp=l(t.startTime))}))}catch(e){console.warn("[TM]: Failed to collect FP:",e)}try{const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection;t&&void 0!==t.rtt&&(e.connectionRtt=t.rtt)}catch(e){console.warn("[TM]: Failed to collect Connection RTT:",e)}try{const t=performance.getEntriesByType("navigation")[0];if(t){const{responseStart:n,requestStart:r}=t;n>0&&r>0&&r<=n&&(e.ttfbRequestTime=l(n-r))}}catch(e){console.warn("[TM]: Failed to collect TTFB Request Time:",e)}try{const t=performance.getEntriesByType("navigation")[0];if(t){const{domContentLoadedEventEnd:n,loadEventEnd:r,fetchStart:o}=t;n>0&&o>0&&(e.dcl=l(n-o)),r>0&&o>0&&(e.loadTime=l(r-o))}}catch(e){console.warn("[TM]: Failed to collect DCL and Load Time:",e)}})(),window.trackMonitor.report({data_type:"performance",event_type:"metrics",event_detail:{traceId:C,data:e}})}))}const Me=e=>{const{client:t,beforeClose:n}=L(e);return P(t.report),!1!==e.traceBehavior&&k(),!1!==e.traceError&&(U(),D(),j(),K()),!1!==e.tracePerformance&&c((()=>{!function(){const e=window.performance||window.msPerformance;if(!e)return{dnsLookupTime:null,tcpConnectTime:null,ttfb:null,transferTime:null,domParseTime:null,domCompleteTime:null,loadEventTime:null,totalPageLoad:null};const t=e.getEntriesByType&&e.getEntriesByType("navigation")&&e.getEntriesByType("navigation")[0];let n=null;if(t)n=t;else{const t=e.timing;t&&(n={startTime:0,domainLookupStart:t.domainLookupStart,domainLookupEnd:t.domainLookupEnd,connectStart:t.connectStart,connectEnd:t.connectEnd,requestStart:t.requestStart,responseStart:t.responseStart,responseEnd:t.responseEnd,domInteractive:t.domInteractive,domComplete:t.domComplete,loadEventEnd:t.loadEventEnd,fetchStart:t.fetchStart},!n.requestStart&&t.fetchStart&&(n.requestStart=t.fetchStart))}const r={dnsLookupTime:n?l(n.domainLookupEnd-n.domainLookupStart):null,tcpConnectTime:n?l(n.connectEnd-n.connectStart):null,ttfb:n?l(n.responseStart-(n.requestStart??n.fetchStart??0)):null,transferTime:n?l(n.responseEnd-n.responseStart):null,domParseTime:n?l(n.domInteractive-n.responseEnd):null,domCompleteTime:n?l(n.domComplete-n.domInteractive):null,loadEventTime:n?l(n.loadEventEnd-(n.domComplete??0)):null,totalPageLoad:n?l((n.loadEventEnd??performance.now())-(n.startTime??0)):null};window.trackMonitor.report({data_type:"performance",event_type:"navigation_timing",event_detail:{traceId:C,data:r}})}(),function(){const e=window.performance||window.msPerformance;if(!e)return[];const t=[];if(e.getEntriesByType){const n=(e.getEntriesByType("resource")||[]).map((e=>{const t="number"==typeof e.redirectEnd&&"number"==typeof e.redirectStart?l(e.redirectEnd-e.redirectStart):null,n="number"==typeof e.domainLookupEnd&&"number"==typeof e.domainLookupStart?l(e.domainLookupEnd-e.domainLookupStart):null,r="number"==typeof e.connectEnd&&"number"==typeof e.connectStart?l(e.connectEnd-e.connectStart):null,o="number"==typeof e.requestStart&&"number"==typeof e.fetchStart?l(e.requestStart-e.fetchStart):null,i="number"==typeof e.responseStart&&"number"==typeof e.requestStart?l(e.responseStart-e.requestStart):null,a="number"==typeof e.responseEnd&&"number"==typeof e.responseStart?l(e.responseEnd-e.responseStart):null,s="number"==typeof e.duration?l(e.duration):null,c="number"==typeof e.startTime?l(e.startTime):null,d="number"==typeof e.transferSize&&isFinite(e.transferSize)&&e.transferSize>=0?Math.round(e.transferSize):null,u="number"==typeof e.encodedBodySize&&isFinite(e.encodedBodySize)&&e.encodedBodySize>=0?Math.round(e.encodedBodySize):null,m="number"==typeof e.decodedBodySize&&isFinite(e.decodedBodySize)&&e.decodedBodySize>=0?Math.round(e.decodedBodySize):null;return{name:e.name,initiatorType:e.initiatorType||"",startTime:c,duration:s,redirectTime:t,cacheTime:o,dnsTime:n,connectTime:r,requestTime:i,responseTime:a,transferSize:d,encodedBodySize:u,decodedBodySize:m}}));n.sort(((e,t)=>(t.duration??0)-(e.duration??0)));for(let e=0;e<Math.min(15,n.length);e++)t.push(n[e])}window.trackMonitor.report({data_type:"performance",event_type:"resource_flow",event_detail:{traceId:C,data:t}})}(),Ie()})),c((()=>{n()})),t};export{Me as default};
@@ -9,8 +9,13 @@ export interface BaseOptions {
9
9
  maxRetries?: number;
10
10
  siteId?: string;
11
11
  channelId: string;
12
- log?: boolean;
13
- behavior?: boolean;
12
+ realTimeUrl?: string;
13
+ realTimeReportInterval?: number;
14
+ isLogger?: boolean;
15
+ traceBehavior?: boolean;
16
+ tracePerformance?: boolean;
17
+ traceError?: boolean;
18
+ errorTraceRate?: number;
14
19
  }
15
20
  export interface SdkReportData {
16
21
  page_url: string;
@@ -33,7 +38,11 @@ export interface ClientReportData {
33
38
  event_detail: any;
34
39
  site_id?: string;
35
40
  channel_id?: string;
41
+ track_real_time?: boolean;
36
42
  }
37
43
  export interface ReportData extends SdkReportData, ClientReportData {
38
44
  }
39
45
  export type ReportFunction = (data: ClientReportData) => void;
46
+ export interface AnyObject {
47
+ [key: string]: any;
48
+ }
@@ -1,3 +1,2 @@
1
- import { ReportFunction } from "@/interface";
2
- export declare const behaviorPlugin: (report: ReportFunction) => void;
1
+ export declare const behaviorPlugin: () => void;
3
2
  export default behaviorPlugin;
@@ -0,0 +1,3 @@
1
+ export declare const submitErrorUuids: string[];
2
+ declare function errorPlugin(): void;
3
+ export default errorPlugin;
@@ -1,3 +1,2 @@
1
1
  import { ReportFunction } from "../interface";
2
- export declare const exposePlugin: (lazyReport: ReportFunction) => void;
3
- export default exposePlugin;
2
+ export declare const exposePlugin: (callback: ReportFunction) => void;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * 收集页面技术性能指标:
3
+ * - dnsLookupTime: DNS 查询耗时(ms)
4
+ * - tcpConnectTime: TCP 建连耗时(ms)
5
+ * - ttfb: 首字节时间(Time To First Byte,ms)
6
+ * - transferTime: 网络传输耗时(response 下载时长,ms)
7
+ * - domParseTime: DOM 解析耗时(从 responseEnd 到 domInteractive,ms)
8
+ * - domCompleteTime: DOM 完整构建耗时(domComplete - domInteractive,ms)
9
+ */
10
+ export interface PerformanceMetrics {
11
+ dnsLookupTime: number | null;
12
+ tcpConnectTime: number | null;
13
+ ttfb: number | null;
14
+ transferTime: number | null;
15
+ domParseTime: number | null;
16
+ domCompleteTime: number | null;
17
+ loadEventTime: number | null;
18
+ totalPageLoad: number | null;
19
+ }
20
+ /**
21
+ * 主函数:收集性能指标并返回对象
22
+ */
23
+ export declare function collectNavigationTiming(): PerformanceMetrics | undefined;
24
+ export declare function collectResourceFlow(): never[] | undefined;
25
+ /**
26
+ * 采集页面性能数据
27
+ */
28
+ /**
29
+ * 采集页面性能数据
30
+ * 使用 web-vitals 库获取 Core Web Vitals 指标 (LCP, CLS, INP, TTFB, FCP)
31
+ */
32
+ export declare function collectPerformanceMetrics(): void;
@@ -0,0 +1 @@
1
+ export declare const proxyFetch: (sendHandler: Function | null | undefined, loadHandler: Function) => void;
@@ -0,0 +1,22 @@
1
+ export declare function parseStackLine(line: string): {
2
+ filename?: undefined;
3
+ functionName?: undefined;
4
+ lineno?: undefined;
5
+ colno?: undefined;
6
+ } | {
7
+ filename: string;
8
+ functionName: string;
9
+ lineno: number | undefined;
10
+ colno: number | undefined;
11
+ };
12
+ export declare function parseStackFrames(error: Error): ({
13
+ filename?: undefined;
14
+ functionName?: undefined;
15
+ lineno?: undefined;
16
+ colno?: undefined;
17
+ } | {
18
+ filename: string;
19
+ functionName: string;
20
+ lineno: number | undefined;
21
+ colno: number | undefined;
22
+ })[];
@@ -34,3 +34,21 @@ export declare const throttle: <T extends (...args: any[]) => void>(fn: T, delay
34
34
  export declare function isTrackElement(element: HTMLElement): Element | undefined;
35
35
  export declare function getNodeXPath(node: Element, curPath?: string): string;
36
36
  export declare const getNavigationType: () => number | string;
37
+ export declare const whenActivated: (callback: () => void) => void;
38
+ /**
39
+ * Runs in the next task after the page is done loading and/or prerendering.
40
+ * @param callback
41
+ */
42
+ export declare const whenReady: (callback: () => void) => void;
43
+ /**
44
+ * 格式化并保留两位小数,若值无效则返回 null
45
+ */
46
+ export declare function safeFixed(v: number | undefined): number | null;
47
+ export declare function getIdGenerator(bytes: number): () => string;
48
+ export declare function generateTraceId(): string;
49
+ export declare function generateSpanId(): string;
50
+ export declare const getErrorKey: (event: ErrorEvent | Event) => "resource" | "cors" | "js";
51
+ export declare const getErrorUuid: (str: string) => string;
52
+ export declare const isChromeExtensionError: (event: ErrorEvent) => boolean;
53
+ export declare function shouldSample(probability: number): boolean;
54
+ export declare function isVisible(element: Element): boolean;
@@ -0,0 +1,7 @@
1
+ import { ReportData } from "@/interface";
2
+ /**
3
+ * 彩色打印埋点数据
4
+ * @param method 上报方式 (SendBeacon | XHR)
5
+ * @param data 上报数据数组
6
+ */
7
+ export declare const logTrackData: (method: 'SendBeacon' | 'XHR', data: ReportData[]) => void;
@@ -0,0 +1,70 @@
1
+ interface HasherState {
2
+ buffer: string;
3
+ buflen: number;
4
+ length: number;
5
+ state: number[];
6
+ }
7
+ export declare class Md5 {
8
+ /**
9
+ * Hash a UTF-8 string on the spot
10
+ * @param str String to hash
11
+ * @param raw Whether to return the value as an `Int32Array`
12
+ */
13
+ static hashStr(str: string, raw?: false): string;
14
+ static hashStr(str: string, raw: true): Int32Array;
15
+ /**
16
+ * Hash a ASCII string on the spot
17
+ * @param str String to hash
18
+ * @param raw Whether to return the value as an `Int32Array`
19
+ */
20
+ static hashAsciiStr(str: string, raw?: false): string;
21
+ static hashAsciiStr(str: string, raw: true): Int32Array;
22
+ private static stateIdentity;
23
+ private static buffer32Identity;
24
+ private static hexChars;
25
+ private static hexOut;
26
+ private static onePassHasher;
27
+ private static _hex;
28
+ private static _md5cycle;
29
+ private _dataLength;
30
+ private _bufferLength;
31
+ private _state;
32
+ private _buffer;
33
+ private _buffer8;
34
+ private _buffer32;
35
+ constructor();
36
+ /**
37
+ * Initialise buffer to be hashed
38
+ */
39
+ start(): this;
40
+ /**
41
+ * Append a UTF-8 string to the hash buffer
42
+ * @param str String to append
43
+ */
44
+ appendStr(str: string): this;
45
+ /**
46
+ * Append an ASCII string to the hash buffer
47
+ * @param str String to append
48
+ */
49
+ appendAsciiStr(str: string): this;
50
+ /**
51
+ * Append a byte array to the hash buffer
52
+ * @param input array to append
53
+ */
54
+ appendByteArray(input: Uint8Array): this;
55
+ /**
56
+ * Get the state of the hash buffer
57
+ */
58
+ getState(): HasherState;
59
+ /**
60
+ * Override the current state of the hash buffer
61
+ * @param state New hash buffer state
62
+ */
63
+ setState(state: HasherState): void;
64
+ /**
65
+ * Hash the current state of the hash buffer and return the result
66
+ * @param raw Whether to return the value as an `Int32Array`
67
+ */
68
+ end(raw?: boolean): Int32Array | string;
69
+ }
70
+ export {};
@@ -0,0 +1,14 @@
1
+ export interface httpMetrics {
2
+ method: string;
3
+ url: string | URL;
4
+ body: Document | XMLHttpRequestBodyInit | null | undefined | ReadableStream;
5
+ requestTime: number;
6
+ responseTime: number;
7
+ status: number;
8
+ statusText: string;
9
+ response?: any;
10
+ timeout: number;
11
+ traceId: string | null;
12
+ duration: number;
13
+ }
14
+ export declare const proxyXmlHttp: (sendHandler: Function | null | undefined, loadHandler: Function) => void;
package/package.json CHANGED
@@ -1,39 +1,40 @@
1
- {
2
- "name": "@tengence/track-sdk-web",
3
- "version": "1.0.0",
4
- "description": "tengence web client track sdk",
5
- "main": "dist/index.mjs",
6
- "module": "dist/index.mjs",
7
- "exports": {
8
- ".": {
9
- "import": {
10
- "types": "./dist/index.d.ts",
11
- "default": "./dist/index.mjs"
12
- }
13
- }
14
- },
15
- "scripts": {
16
- "build": "rollup --c rollup.config.ts --configPlugin typescript",
17
- "release": "npm publish --access public"
18
- },
19
- "private": false,
20
- "author": "tengence",
21
- "license": "ISC",
22
- "devDependencies": {
23
- "@rollup/plugin-alias": "^5.1.1",
24
- "@rollup/plugin-commonjs": "^28.0.1",
25
- "@rollup/plugin-json": "^6.1.0",
26
- "@rollup/plugin-node-resolve": "^15.3.0",
27
- "@rollup/plugin-terser": "^0.4.4",
28
- "@rollup/plugin-typescript": "^12.1.1",
29
- "@types/node": "^22.13.1",
30
- "cors": "^2.8.5",
31
- "express": "^4.21.2",
32
- "rollup": "^4.34.6",
33
- "tslib": "^2.8.0",
34
- "typescript": "^4.9.5"
35
- },
36
- "files": [
37
- "dist"
38
- ]
39
- }
1
+ {
2
+ "name": "@tengence/track-sdk-web",
3
+ "version": "1.1.1",
4
+ "description": "tengence web client track sdk",
5
+ "main": "dist/index.mjs",
6
+ "module": "dist/index.mjs",
7
+ "exports": {
8
+ ".": {
9
+ "import": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.mjs"
12
+ }
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "rollup --c rollup.config.ts --configPlugin typescript",
17
+ "release": "npm publish --access public --registry https://registry.npmjs.org/"
18
+ },
19
+ "private": false,
20
+ "author": "tengence",
21
+ "license": "ISC",
22
+ "devDependencies": {
23
+ "@rollup/plugin-alias": "^5.1.1",
24
+ "@rollup/plugin-commonjs": "^28.0.1",
25
+ "@rollup/plugin-json": "^6.1.0",
26
+ "@rollup/plugin-node-resolve": "^15.3.0",
27
+ "@rollup/plugin-terser": "^0.4.4",
28
+ "@rollup/plugin-typescript": "^12.1.1",
29
+ "@types/node": "^22.13.1",
30
+ "cors": "^2.8.5",
31
+ "express": "^4.21.2",
32
+ "rollup": "^4.34.6",
33
+ "tslib": "^2.8.0",
34
+ "typescript": "^4.9.5",
35
+ "web-vitals": "^5.1.0"
36
+ },
37
+ "files": [
38
+ "dist"
39
+ ]
40
+ }