ci-trap-web
Version:
Lightweight mouse and touch event tracker library for browsers.
2 lines (1 loc) • 20.1 kB
JavaScript
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("rfdc/default"),t=require("fflate"),s=require("uuid"),i=require("js-cookie"),n=require("platform");function a(e){let{prototype:t}=e.constructor;const s=(t,s)=>{if("constructor"===s)return;const i=Reflect.getOwnPropertyDescriptor(t,s);i&&"function"==typeof i.value&&(e[s]=e[s].bind(e))};do{Array.from(Reflect.ownKeys(t),(e=>s(t,e))),t=Reflect.getPrototypeOf(t)}while(t!==Object.prototype)}const r={on(e,t){this._eventHandlers||(this._eventHandlers={}),this._eventHandlers[e]||(this._eventHandlers[e]=[]),this._eventHandlers[e].push(t)},off(e,t){this._eventHandlers&&this._eventHandlers[e]&&(this._eventHandlers[e]=this._eventHandlers[e].filter((e=>e!==t)))},emit(e,...t){this._eventHandlers?.[e]&&this._eventHandlers[e].forEach((e=>e.apply(this,t)))}},o="ontouchstart"in window||"onmsgesturestart"in window,h="onpointermove"in window||"onmspointermove"in window,l="onvisibilitychange"in document||"onmozvisibilitychange"in document||"onmsvisibilitychange"in document||"onwebkitvisibilitychange"in document,u="onfreeze"in document,m="active",c="inactive";const d=new class{constructor(){a(this),this.actualizeEpoch()}currentTs(){return performance.now()+this._epoch}convertEventTimeToTs(e){return e<1e12?e+this._epoch:e}actualizeEpoch(){const e=performance.now(),t=(new Date).getTime();this._epoch=t-e}},p={passive:!0,capture:!0};class v{constructor(){a(this),this._registeredElements=[],this._captureCoalescedEvents=!0,this._requestAnimationFrameId=void 0}mountGlobal(){this._registeredElements.length>0||(l?document.addEventListener("visibilitychange",this.handleVisibilityChange):window.addEventListener("pagehide",this.handlePageHide),u&&document.addEventListener("freeze",this.handleFreeze),window.addEventListener("blur",this.handleBlur),window.addEventListener("focus",this.handleFocus),window.addEventListener("scroll",this.handleScroll))}umountGlobal(){this._registeredElements.length>0||(l?document.removeEventListener("visibilitychange",this.handleVisibilityChange):window.removeEventListener("pagehide",this.handlePageHide),u&&document.removeEventListener("freeze",this.handleFreeze),window.removeEventListener("blur",this.handleBlur),window.removeEventListener("focus",this.handleFocus),window.removeEventListener("scroll",this.handleScroll))}mount(e){this._registeredElements.includes(e)||(this.mountGlobal(),o?(e.addEventListener("touchstart",this.handleTouchStart,p),e.addEventListener("touchmove",this.handleTouchMove,p),e.addEventListener("touchend",this.handleTouchEnd,p)):h?(e.addEventListener("pointermove",this.handlePointerMove,p),e.addEventListener("pointerdown",this.handlePointerDown,p),e.addEventListener("pointerup",this.handlePointerUp,p)):(e.addEventListener("mousemove",this.handleMouseMove,p),e.addEventListener("mousedown",this.handleMouseDown,p),e.addEventListener("mouseup",this.handleMouseUp,p)),e.addEventListener("wheel",this.handleWheel,p),this._registeredElements.push(e))}umount(e){if(!this._registeredElements.includes(e))return;o?(e.removeEventListener("touchstart",this.handleTouchStart,p),e.removeEventListener("touchmove",this.handleTouchMove,p),e.removeEventListener("touchend",this.handleTouchEnd,p)):h?(e.removeEventListener("pointermove",this.handlePointerMove,p),e.removeEventListener("pointerdown",this.handlePointerDown,p),e.removeEventListener("pointerup",this.handlePointerUp,p)):(e.removeEventListener("mousemove",this.handleMouseMove,p),e.removeEventListener("mousedown",this.handleMouseDown,p),e.removeEventListener("mouseup",this.handleMouseUp,p)),e.removeEventListener("wheel",this.handleWheel,p);const t=this._registeredElements.indexOf(e);this._registeredElements.splice(t,1),this.umountGlobal()}push(...e){this.emit("message",e)}requestSubmission(){this.emit("requestSubmission")}captureCoalescedEvents(e){this._captureCoalescedEvents=e}handlePointerMove(e){let t=[];this._captureCoalescedEvents&&e.getCoalescedEvents&&(t=e.getCoalescedEvents()),0===t.length?this.handleSinglePointerMove(e,!1):t.forEach(((e,s)=>{this.handleSinglePointerMove(e,s!==t.length-1)}))}handleSinglePointerMove(e,t){switch(e.pointerType){case"mouse":this.handleMouseMove(e,t);break;case"touch":this.push(3,d.convertEventTimeToTs(e.timeStamp),e.pointerId,e.screenX,e.screenY,t?1:0)}}handlePointerDown(e){switch(e.pointerType){case"mouse":this.handleMouseDown(e);break;case"touch":this.push(2,d.convertEventTimeToTs(e.timeStamp),e.pointerId,e.screenX,e.screenY)}}handlePointerUp(e){switch(e.pointerType){case"mouse":this.handleMouseUp(e);break;case"touch":this.push(4,d.convertEventTimeToTs(e.timeStamp),e.pointerId,e.screenX,e.screenY)}}handleMouseMove(e,t){this.push(0,d.convertEventTimeToTs(e.timeStamp),e.screenX,e.screenY,e.buttons,t?1:0)}handleMouseDown(e){this.push(5,d.convertEventTimeToTs(e.timeStamp),e.screenX,e.screenY,e.buttons,e.button)}handleMouseUp(e){this.push(6,d.convertEventTimeToTs(e.timeStamp),e.screenX,e.screenY,e.buttons,e.button)}handleTouchStart(e){this.iterateTouches(e,(t=>{this.push(2,d.convertEventTimeToTs(e.timeStamp),t.identifier,t.screenX,t.screenY)}))}handleTouchMove(e){this.iterateTouches(e,(t=>{this.push(3,d.convertEventTimeToTs(e.timeStamp),t.identifier,t.screenX,t.screenY,0)}))}handleTouchEnd(e){this.iterateTouches(e,(t=>{this.push(4,d.convertEventTimeToTs(e.timeStamp),t.identifier,t.screenX,t.screenY)}))}iterateTouches(e,t){Array.from(e.changedTouches).forEach(t)}handleWheel(e){this.push(9,d.convertEventTimeToTs(e.timeStamp),e.deltaX,e.deltaY,e.deltaZ,e.deltaMode)}handleScroll(e){this.push(10,d.convertEventTimeToTs(e.timeStamp),window.scrollX,window.scrollY)}handleVisibilityChange(){"hidden"===document.visibilityState&&this.requestSubmission()}handlePageHide(){this.requestSubmission()}handleFreeze(){this.requestSubmission()}handleBlur(e){this.push(7,d.convertEventTimeToTs(e.timeStamp),e),this.requestSubmission(),this.emit("pageStateChanged",c)}handleFocus(e){d.actualizeEpoch(),this.emit("pageStateChanged",m),this.push(8,d.convertEventTimeToTs(e.timeStamp),e)}startRequestAnimationFrame(){this._requestAnimationFrameId=requestAnimationFrame(this.onRequestAnimationFrame)}stopRequestAnimationFrame(){void 0!==this._requestAnimationFrameId&&(cancelAnimationFrame(this._requestAnimationFrameId),this._requestAnimationFrameId=void 0)}onRequestAnimationFrame(e){this._requestAnimationFrameId=requestAnimationFrame(this.onRequestAnimationFrame),this.push(20,d.convertEventTimeToTs(e))}}Object.assign(v.prototype,r);class f{constructor(){a(this),this._enabled=!0,this._buffer=[],this._headerItems=[],this._bufferSizeLimit=3600,this._bufferTimeout=12e4,this._bufferTimer=null,this._idleTimeout=2e3,this._idleTimer=null,this._inactiveTimeout=59e3,this._inactiveTimer=null,this._inactive=!1}set bufferSizeLimit(e){this._bufferSizeLimit=e}set bufferTimeout(e){this._bufferTimeout=e,this.setBufferTimer()}clearBufferTimer(){this._bufferTimer&&(window.clearTimeout(this._bufferTimer),this._bufferTimer=null)}setBufferTimer(){this._bufferTimer||"number"==typeof this._bufferTimeout&&(this._bufferTimer=window.setTimeout(this.requestSubmission,this._bufferTimeout))}set idleTimeout(e){this._idleTimeout=e,this.setIdleTimer()}set inactiveTimeout(e){this._inactiveTimeout=e,this.setInactiveTimer()}clearIdleTimer(){this._idleTimer&&(window.clearTimeout(this._idleTimer),this._idleTimer=null)}setIdleTimer(){"number"==typeof this._idleTimeout&&(this._idleTimer=window.setTimeout(this.requestSubmission,this._idleTimeout))}setInactiveTimer(){"number"==typeof this._inactiveTimeout&&(this._inactiveTimer=window.setTimeout(this.bufferInactive,this._inactiveTimeout))}clearInactiveTimer(){this._inactiveTimer&&(window.clearTimeout(this._inactiveTimer),this._inactiveTimer=null)}push(e,t,...s){if(!this._enabled)return;const i=[e,t,...s];this.bufferActive(),this.clearInactiveTimer(),this.clearIdleTimer(),this._buffer.push(i),this.setInactiveTimer(),this.setIdleTimer(),this.setBufferTimer(),this._buffer.length>=this._bufferSizeLimit&&this.requestSubmission()}addHeaderItem(...e){this._headerItems.push([...e])}flush(){this.clearIdleTimer(),this.clearBufferTimer();const e=this._headerItems.concat(this._buffer);return this._buffer.length=0,this._headerItems.length=0,e}isEmpty(){return 0===this._buffer.length}bufferInactive(){return this._inactive=!0,this.emit("bufferInactive")}bufferActive(){return this._inactive?(this._inactive=!1,this.emit("bufferActive")):null}requestSubmission(e){return this.emit("requestSubmission",e)}enable(){this._enabled=!0,this._inactive=!1,this.setIdleTimer(),this.setBufferTimer(),this.setInactiveTimer()}disable(){this.clearInactiveTimer(),this.clearIdleTimer(),this.clearBufferTimer(),this.requestSubmission(!0),this._enabled=!1,this._headerItems.length=0}collectedEvents(){return e(this._buffer)}}Object.assign(f.prototype,r);class b{constructor(e){a(this),this._metadata=e,this._enableCompression=false,this._url=this.createUrl("?UNCONFIGURED=http")}set url(e){this._url=this.createUrl(e)}createUrl(e){const t=new URL(e,window.location);return t.pathname=t.pathname.replace("$%7BsessionId%7D",this._metadata.sessionId).replace("$%7BstreamId%7D",this._metadata.streamId),t}async submit(e){this.emit("dataSubmitted",e)}}Object.assign(b.prototype,r);class _ extends b{constructor(e,t=!1){super(e,t),a(this)}set enableCompression(e){this._enableCompression=!!e}async submit(e){super.submit(e);const s=this._enableCompression?t.zlibSync(t.strToU8(JSON.stringify(e)),{level:9,mem:10}):JSON.stringify(e);let i="text/plain";"string"==typeof this._metadata.apiKeyName&&""!==this._metadata.apiKeyName&&"string"==typeof this._metadata.apiKeyValue&&""!==this._metadata.apiKeyValue&&(i+=`; ${this._metadata.apiKeyName}=${this._metadata.apiKeyValue}`),i+="; encoding=json"+(this._enableCompression?"+zlib":""),await fetch(this._url.href,{method:"POST",mode:"cors",cache:"no-cache",credentials:"omit",headers:{"Content-Type":i},redirect:"follow",referrerPolicy:"origin",body:s})}close(){}}class g extends b{constructor(e,t,s=!1){super(e,s),a(this),this._logger=t,this._socket=null}set enableCompression(e){this.logger("unnecessary enableCompression call")}set url(e){this._socket&&(this._socket.close(),this._socket=null),super.url=e}async submit(e){super.submit(e),null===this._socket&&await this.initializeSocket(),await this._socket.send(JSON.stringify(e))}async initializeSocket(){const e=this._url;!e.protocol.match("ws")&&e.protocol.match("http")&&(e.protocol=e.protocol.replace("http","ws")),this._socket=new WebSocket(e),await this.setupListenersOnConnect()}setupListenersOnConnect(){const e=this._socket;return new Promise(((t,s)=>{e.addEventListener("error",(e=>{this._logger(`WebSocket connection error: ${e}`),s(new Error(e))})),e.addEventListener("open",(()=>{e.addEventListener("close",(()=>{this._logger("WebsSocket connection closed"),this._socket=null})),t()}))}))}close(){null!=this._socket&&this._socket.close()}}class T extends b{constructor(e,t){super(e,t),a(this)}set enableCompression(e){}close(){}}class w{constructor(){a(this),this._inMemoryEventStorage=[],this._sizeLimit=1e4}get sizeLimit(){return this._sizeLimit}set sizeLimit(e){this._sizeLimit=e}get inMemoryEventStorage(){return this._inMemoryEventStorage}set inMemoryEventStorage(e){this._inMemoryEventStorage=e}onDataSubmitted(e){this.inMemoryEventStorage.push(e),this.cleanUpInMemoryBufferIfNeeded()}flushStorage(){const e=this.inMemoryEventStorage.flat();return this.inMemoryEventStorage=[],e}cleanUpInMemoryBufferIfNeeded(){let e=this.eventCount();for(;e>this.sizeLimit;){e-=this.inMemoryEventStorage.shift().length}}eventCount(){return this.inMemoryEventStorage.reduce(((e,t)=>e+t.length),0)}collectedEvents(){return e(this.inMemoryEventStorage.flat())}}const S={name:"ci-trap-web",version:"1.0.21",type:"collector"};class E{constructor(){a(this),this._sessionId=(()=>{let e=i.get("sessionId");return"string"!=typeof e&&(e=s.v4(),i.set("sessionId",e,{path:"/",sameSite:"none",secure:!0})),e})(),this.generateNewStreamId(),this._customMetadata={},this._apiKeyName="GRABOXY-API-KEY",this._apiKeyValue="UNCONFIGURED",this._metadataSubmissionInterval=6e4,this._collectUrls=true,this._components=[S]}get sessionId(){return this._sessionId}get streamId(){return this._streamId}get apiKeyName(){return this._apiKeyName}set apiKeyName(e){this._apiKeyName=e}get apiKeyValue(){return this._apiKeyValue}set apiKeyValue(e){this._apiKeyValue=e}get metadataSubmissionInterval(){return this._metadataSubmissionInterval}set metadataSubmissionInterval(e){this._metadataSubmissionInterval=e,void 0!==this._submissionTimer&&(window.clearInterval(this._submissionTimer),this._submissionTimer=window.setInterval(this.submit,this.metadataSubmissionInterval))}get collectUrls(){return this._collectUrls}set collectUrls(e){this._collectUrls=e}set components(e){this._components=[S,...e]}get schema(){return{version:"1-0-0",components:this._components}}enable(){void 0===this._submissionTimer&&(this._submissionTimer=window.setInterval(this.submit,this.metadataSubmissionInterval),this.submit())}disable(){void 0!==this._submissionTimer&&(window.clearInterval(this._submissionTimer),this._submissionTimer=void 0)}submit(){this.emit("message",this.serializeMetadata())}reset(){this.disable(),this.enable()}generateNewStreamId(){this._streamId=s.v4()}serializeMetadata(){return[11,d.currentTs(),{platform:this.platform,location:this.location,custom:this.custom,screen:this.screen,document:this.document}]}set(e,t){this._customMetadata[e]=t,this.submit()}remove(e){delete this._customMetadata[e],this.submit()}get custom(){return e(this._customMetadata)}get platform(){return{description:n.description,layout:n.layout,manufacturer:n.manufacturer,name:n.name,prerelease:n.prerelease,product:n.product,ua:n.ua,version:n.version,os:{architecture:n.os.architecture,family:n.os.family,version:n.os.version}}}get location(){return this.collectUrls?{current:window.location.href,previous:document.referrer}:{}}get screen(){const{screen:e}=window;return{availHeight:e.availHeight,availWidth:e.availWidth,availLeft:e.availLeft,availTop:e.availTop,height:e.height,width:e.width,top:e.top,left:e.left,colorDepth:e.colorDepth,pixelDepth:e.pixelDepth,devicePixelRatio:window.devicePixelRatio,orientation:{...this.orientation}}}get orientation(){let e,t;return window.screen.orientation?(e=window.screen.orientation.type,t=window.screen.orientation.angle):"number"==typeof window.orientation&&(e=90===Math.abs(window.orientation)?"landscape":"portrait",t=window.orientation),{type:e,angle:t}}get document(){const{documentElement:e}=document;return{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop,scrollHeight:e.scrollHeight,scrollWidth:e.scrollWidth,offsetHeight:e.offsetHeight,offsetWidth:e.offsetWidth,clientTop:e.clientTop,clientLeft:e.clientLeft,clientHeight:e.clientHeight,clientWidth:e.clientWidth}}}Object.assign(E.prototype,r);const y={disableTouchEvents(e){o&&(e.dataset.oldTouchAction||(e.dataset.oldTouchAction=e.style.touchAction),e.style.touchAction="none")},restoreTouchEvents(e){o&&(e.style.touchAction=e.dataset.oldTouchAction,delete e.dataset.oldTouchAction)}};class I{constructor(){a(this),this._buffer=new f(this),this._metadata=new E,this._handlers=new v,this.state={logger:(...e)=>{console.log(...e)},transport:new _(this._metadata,this._buffer),sequenceNumber:0,eventStorage:new w,collectEvents:!1,captureRequestAnimationFrame:!1,onDataSubmittedCallback:void 0,restartOnBecomingActive:!1,isRunning:!1,stopDataCollectionOnPageHide:!1},this._handlers.on("message",this.pushMessage),this._metadata.on("message",this.pushMessage),this._handlers.on("requestSubmission",this.submit),this._buffer.on("requestSubmission",this.submit),this._handlers.on("pageStateChanged",this.onPageStateChanged),this._buffer.on("bufferInactive",this._metadata.disable),this._buffer.on("bufferActive",this._metadata.enable),I.instance||(I.instance=this)}streamId(){return this._metadata.streamId}sessionId(){return this._metadata.sessionId}apiKeyName(e){this._metadata.apiKeyName=e}apiKeyValue(e){this._metadata.apiKeyValue=e}apiKey(e){this._metadata.apiKeyValue=e}components(e){this._metadata.components=e}mount(e){this._handlers.mount(e)}umount(e){this._handlers.umount(e)}idleTimeout(e){this._buffer.idleTimeout=e}inactiveTimeout(e){this._buffer.inactiveTimeout=e}start(){this._buffer.enable(),this.addHeaderToBuffer(),this._metadata.enable(),this.state.captureRequestAnimationFrame&&this._handlers.startRequestAnimationFrame(),this.state.isRunning=!0}stop(){this.submit(!0),this._buffer.disable(),this._metadata.disable(),this._handlers.stopRequestAnimationFrame(),this.state.isRunning=!1}bufferSizeLimit(e){this._buffer.bufferSizeLimit=e}bufferTimeout(e){this._buffer.bufferTimeout=e}enableCompression(e){this.state.transport.enableCompression=e}url(e){this.state.transport.url=e}send(e){"string"==typeof e?this.pushMessage([1,d.currentTs(),{message:e}]):"object"==typeof e&&this.pushMessage([1,d.currentTs(),e])}pushMessage(e){this._buffer.push(...e)}submit(e){if(this._buffer.isEmpty())return Promise.resolve();const t=this._buffer.flush();return e||this.addHeaderToBuffer(),this.state.transport.submit(t)}addHeaderToBuffer(){const e=this.state.sequenceNumber++;this._buffer.addHeaderItem(-1,d.currentTs(),this._metadata.sessionId,this._metadata.streamId,e,this._metadata.schema)}metadata(e,t){this.addCustomMetadata(e,t)}addCustomMetadata(e,t){this._metadata.set(e,t)}removeCustomMetadata(e){this._metadata.remove(e)}customMetadata(){return this._metadata.custom}setLogDestination(e){switch(typeof e){case"string":e=document.getElementById(e);case"object":this.state.logger=(...t)=>{e.innerHTML=`${t.join()}\n${e.innerHTML}`};break;default:this.state.logger=(...e)=>{console.log(...e)}}}setUseWsTransport(e){this.setTransportMethod(e?"ws":"http")}setTransportMethod(e){this.state.transport.off("dataSubmitted",this.state.eventStorage.onDataSubmitted),this.state.transport.off("dataSubmitted",this.state.onDataSubmittedCallback),this.state.transport.close(),e.startsWith("ws")?this.state.transport=new g(this._metadata,this.log):e.startsWith("http")?this.state.transport=new _(this._metadata):this.state.transport=new T(this._metadata),this.state.collectEvents&&this.state.transport.on("dataSubmitted",this.state.eventStorage.onDataSubmitted),this.state.onDataSubmittedCallback&&this.state.transport.on("dataSubmitted",this.state.onDataSubmittedCallback)}setCollectEvents(e){this.state.collectEvents=e,e?this.state.transport.on("dataSubmitted",this.state.eventStorage.onDataSubmitted):this.state.transport.off("dataSubmitted",this.state.eventStorage.onDataSubmitted)}setEventCollectionSizeLimit(e){this.state.eventStorage.sizeLimit=e}setMetadataSubmissionInterval(e){this._metadata.metadataSubmissionInterval=e}setMetadataCollectUrls(e){this._metadata.collectUrls=e}submitMetadata(){this._metadata.submit()}setCaptureCoalescedEvents(e){this._handlers.captureCoalescedEvents(e)}setCaptureRequestAnimationFrame(e){this.state.captureRequestAnimationFrame=e,e?this._handlers.startRequestAnimationFrame():this._handlers.stopRequestAnimationFrame()}log(...e){this.state.logger(...e)}collectedEvents(){return this.state.eventStorage.collectedEvents().concat(this._buffer.collectedEvents())}collectedEventCount(e=(()=>!0)){return this.collectedEvents().filter(e).length}generateNewStreamId(){this._metadata.generateNewStreamId()}flushCollectedEvents(){return this.state.eventStorage.flushStorage()}onDataSubmitted(e){this.state.transport.off("dataSubmitted",this.state.onDataSubmittedCallback),this.state.onDataSubmittedCallback=e,this.state.onDataSubmittedCallback&&this.state.transport.on("dataSubmitted",this.state.onDataSubmittedCallback)}stopDataCollectionOnPageHide(e){this.state.stopDataCollectionOnPageHide=e}onPageStateChanged(e){e===c&&this.state.isRunning&&this.state.stopDataCollectionOnPageHide?(this.stop(),this.state.restartOnBecomingActive=!0):e===m&&this.state.restartOnBecomingActive&&(this.start(),this.state.restartOnBecomingActive=!1)}}Object.assign(I.prototype,y);const M=new I;Object.freeze(M),exports.Trap=I,exports.default=M;