@tekibo/feedpulse-sdk 2.1.3 → 2.1.4

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";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class n{constructor(e){this.queue=[],this.flushInterval=null,this.observer=null,this.intersectionObserver=null,this.seenInView=new Set;const i="https://feed-pulse.vercel.app/api/ingest";this.config={apiKey:e.apiKey,endpoint:e.endpoint??i,batchInterval:e.batchInterval??5e3},this.visitorId="",this.sessionId=""}init(){this.isBrowser()&&(this.visitorId=this.getOrCreateVisitorId(),this.sessionId=this.generateSessionId(),this.startFlushInterval(),this.attachGlobalListeners(),this.observeDOM())}attachGlobalListeners(){document.addEventListener("click",t=>{const r=t.target.closest("[data-fp-id]");r&&this.track("click",r.getAttribute("data-fp-id"),{x:t.clientX,y:t.clientY})},{passive:!0});let e=0,i=null;document.addEventListener("mouseover",t=>{const r=t.target.closest("[data-fp-id]");r&&(e=Date.now(),i=r.getAttribute("data-fp-id"))},{passive:!0}),document.addEventListener("mouseout",t=>{if(!t.target.closest("[data-fp-id]")||!i)return;const s=Date.now()-e;s>500&&this.track("hover",i,{hoverDuration:s}),i=null},{passive:!0})}observeDOM(){this.intersectionObserver=new IntersectionObserver(i=>{for(const t of i){const r=t.target.dataset.fpId;!r||!t.isIntersecting||this.seenInView.has(r)||(this.seenInView.add(r),this.track("scroll_into_view",r,{scrollDepth:Math.round(window.scrollY/Math.max(1,document.body.scrollHeight)*100)}))}},{threshold:.5});const e=()=>{document.querySelectorAll("[data-fp-id]").forEach(i=>{this.intersectionObserver?.observe(i)})};e(),this.observer=new MutationObserver(()=>e()),this.observer.observe(document.body,{childList:!0,subtree:!0})}track(e,i,t){this.isBrowser()&&this.queue.push({projectApiKey:this.config.apiKey,elementId:i,eventType:e,sessionId:this.sessionId,visitorId:this.visitorId,page:window.location.pathname,referrer:document.referrer,device:this.getDeviceType(),browser:this.getBrowser(),os:this.getOS(),metadata:t,timestamp:new Date().toISOString()})}trackFeedback(e,i,t){this.isBrowser()&&(!i&&!t||this.sendImmediate([{projectApiKey:this.config.apiKey,elementId:e??"__page__",eventType:"feedback",sessionId:this.sessionId,visitorId:this.visitorId,page:window.location.pathname,device:this.getDeviceType(),metadata:{rating:i,message:t},timestamp:new Date().toISOString()}]))}async flush(){if(this.queue.length===0)return;const e=[...this.queue];this.queue=[],await this.sendImmediate(e)}async sendImmediate(e){try{await fetch(this.config.endpoint,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({events:e}),keepalive:!0})}catch{}}startFlushInterval(){this.flushInterval=setInterval(()=>this.flush(),this.config.batchInterval),window.addEventListener("beforeunload",()=>this.flush()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush()})}getOrCreateVisitorId(){const e="__fp_vid",i=this.generateId();try{let t=localStorage.getItem(e);return t||(t=i,localStorage.setItem(e,t)),t}catch{return i}}generateId(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`}isBrowser(){return typeof window<"u"&&typeof document<"u"}generateSessionId(){return`${Date.now()}-${Math.random().toString(36).slice(2)}`}getDeviceType(){const e=navigator.userAgent;return/Mobi|Android/i.test(e)?"mobile":/Tablet|iPad/i.test(e)?"tablet":"desktop"}getBrowser(){const e=navigator.userAgent;return e.includes("Edg")?"Edge":e.includes("Chrome")?"Chrome":e.includes("Firefox")?"Firefox":e.includes("Safari")?"Safari":"Other"}getOS(){const e=navigator.userAgent;return e.includes("Windows")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":/iPhone|iOS/.test(e)?"iOS":"Other"}destroy(){this.flushInterval&&clearInterval(this.flushInterval),this.observer?.disconnect(),this.intersectionObserver?.disconnect(),this.flush()}}exports.FeedPulseTracker=n;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class c{constructor(e){this.queue=[],this.flushInterval=null,this.observer=null,this.intersectionObserver=null,this.scrollFallbackListener=null,this.resizeFallbackListener=null,this.seenInView=new Set;const i="https://feed-pulse.vercel.app/api/ingest";this.config={apiKey:e.apiKey,endpoint:e.endpoint??i,batchInterval:e.batchInterval??5e3},this.visitorId="",this.sessionId=""}init(){this.isBrowser()&&(this.visitorId=this.getOrCreateVisitorId(),this.sessionId=this.generateSessionId(),this.startFlushInterval(),this.attachGlobalListeners(),this.observeDOM())}attachGlobalListeners(){document.addEventListener("click",t=>{const r=t.target.closest("[data-fp-id]");r&&this.track("click",r.getAttribute("data-fp-id"),{x:t.clientX,y:t.clientY})},{passive:!0});let e=0,i=null;document.addEventListener("mouseover",t=>{const r=t.target.closest("[data-fp-id]");r&&(e=Date.now(),i=r.getAttribute("data-fp-id"))},{passive:!0}),document.addEventListener("mouseout",t=>{if(!t.target.closest("[data-fp-id]")||!i)return;const s=Date.now()-e;s>500&&this.track("hover",i,{hoverDuration:s}),i=null},{passive:!0})}observeDOM(){const e=r=>{this.seenInView.has(r)||(this.seenInView.add(r),this.track("scroll_into_view",r,{scrollDepth:Math.round(window.scrollY/Math.max(1,document.body.scrollHeight)*100)}))};this.intersectionObserver=new IntersectionObserver(r=>{for(const s of r){const n=s.target.dataset.fpId;!n||!s.isIntersecting||e(n)}},{threshold:.1});const i=()=>{document.querySelectorAll("[data-fp-id]").forEach(r=>{this.intersectionObserver?.observe(r)})},t=()=>{const r=window.innerHeight*.1,s=window.innerHeight*.9;document.querySelectorAll("[data-fp-id]").forEach(n=>{const o=n.dataset.fpId;if(!o||this.seenInView.has(o))return;const a=n.getBoundingClientRect();a.bottom>=r&&a.top<=s&&e(o)})};i(),t(),this.scrollFallbackListener=()=>t(),this.resizeFallbackListener=()=>t(),window.addEventListener("scroll",this.scrollFallbackListener,{passive:!0}),window.addEventListener("resize",this.resizeFallbackListener,{passive:!0}),this.observer=new MutationObserver(()=>i()),this.observer.observe(document.body,{childList:!0,subtree:!0})}track(e,i,t){this.isBrowser()&&this.queue.push({projectApiKey:this.config.apiKey,elementId:i,eventType:e,sessionId:this.sessionId,visitorId:this.visitorId,page:window.location.pathname,referrer:document.referrer,device:this.getDeviceType(),browser:this.getBrowser(),os:this.getOS(),metadata:t,timestamp:new Date().toISOString()})}trackFeedback(e,i,t){this.isBrowser()&&(!i&&!t||this.sendImmediate([{projectApiKey:this.config.apiKey,elementId:e??"__page__",eventType:"feedback",sessionId:this.sessionId,visitorId:this.visitorId,page:window.location.pathname,device:this.getDeviceType(),metadata:{rating:i,message:t},timestamp:new Date().toISOString()}]))}async flush(){if(this.queue.length===0)return;const e=[...this.queue];this.queue=[],await this.sendImmediate(e)}async sendImmediate(e){try{await fetch(this.config.endpoint,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({events:e}),keepalive:!0})}catch{}}startFlushInterval(){this.flushInterval=setInterval(()=>this.flush(),this.config.batchInterval),window.addEventListener("beforeunload",()=>this.flush()),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush()})}getOrCreateVisitorId(){const e="__fp_vid",i=this.generateId();try{let t=localStorage.getItem(e);return t||(t=i,localStorage.setItem(e,t)),t}catch{return i}}generateId(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2)}`}isBrowser(){return typeof window<"u"&&typeof document<"u"}generateSessionId(){return`${Date.now()}-${Math.random().toString(36).slice(2)}`}getDeviceType(){const e=navigator.userAgent;return/Mobi|Android/i.test(e)?"mobile":/Tablet|iPad/i.test(e)?"tablet":"desktop"}getBrowser(){const e=navigator.userAgent;return e.includes("Edg")?"Edge":e.includes("Chrome")?"Chrome":e.includes("Firefox")?"Firefox":e.includes("Safari")?"Safari":"Other"}getOS(){const e=navigator.userAgent;return e.includes("Windows")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":/iPhone|iOS/.test(e)?"iOS":"Other"}destroy(){this.flushInterval&&clearInterval(this.flushInterval),this.scrollFallbackListener&&window.removeEventListener("scroll",this.scrollFallbackListener),this.resizeFallbackListener&&window.removeEventListener("resize",this.resizeFallbackListener),this.observer?.disconnect(),this.intersectionObserver?.disconnect(),this.flush()}}exports.FeedPulseTracker=c;
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- class o {
1
+ class l {
2
2
  constructor(e) {
3
- this.queue = [], this.flushInterval = null, this.observer = null, this.intersectionObserver = null, this.seenInView = /* @__PURE__ */ new Set();
3
+ this.queue = [], this.flushInterval = null, this.observer = null, this.intersectionObserver = null, this.scrollFallbackListener = null, this.resizeFallbackListener = null, this.seenInView = /* @__PURE__ */ new Set();
4
4
  const i = "https://feed-pulse.vercel.app/api/ingest";
5
5
  this.config = {
6
6
  apiKey: e.apiKey,
@@ -31,20 +31,32 @@ class o {
31
31
  }, { passive: !0 });
32
32
  }
33
33
  observeDOM() {
34
- this.intersectionObserver = new IntersectionObserver((i) => {
35
- for (const t of i) {
36
- const r = t.target.dataset.fpId;
37
- !r || !t.isIntersecting || this.seenInView.has(r) || (this.seenInView.add(r), this.track("scroll_into_view", r, {
38
- scrollDepth: Math.round(window.scrollY / Math.max(1, document.body.scrollHeight) * 100)
39
- }));
34
+ const e = (r) => {
35
+ this.seenInView.has(r) || (this.seenInView.add(r), this.track("scroll_into_view", r, {
36
+ scrollDepth: Math.round(window.scrollY / Math.max(1, document.body.scrollHeight) * 100)
37
+ }));
38
+ };
39
+ this.intersectionObserver = new IntersectionObserver((r) => {
40
+ for (const s of r) {
41
+ const n = s.target.dataset.fpId;
42
+ !n || !s.isIntersecting || e(n);
40
43
  }
41
- }, { threshold: 0.5 });
42
- const e = () => {
43
- document.querySelectorAll("[data-fp-id]").forEach((i) => {
44
- this.intersectionObserver?.observe(i);
44
+ }, { threshold: 0.1 });
45
+ const i = () => {
46
+ document.querySelectorAll("[data-fp-id]").forEach((r) => {
47
+ this.intersectionObserver?.observe(r);
48
+ });
49
+ }, t = () => {
50
+ const r = window.innerHeight * 0.1, s = window.innerHeight * 0.9;
51
+ document.querySelectorAll("[data-fp-id]").forEach((n) => {
52
+ const o = n.dataset.fpId;
53
+ if (!o || this.seenInView.has(o))
54
+ return;
55
+ const a = n.getBoundingClientRect();
56
+ a.bottom >= r && a.top <= s && e(o);
45
57
  });
46
58
  };
47
- e(), this.observer = new MutationObserver(() => e()), this.observer.observe(document.body, { childList: !0, subtree: !0 });
59
+ i(), t(), this.scrollFallbackListener = () => t(), this.resizeFallbackListener = () => t(), window.addEventListener("scroll", this.scrollFallbackListener, { passive: !0 }), window.addEventListener("resize", this.resizeFallbackListener, { passive: !0 }), this.observer = new MutationObserver(() => i()), this.observer.observe(document.body, { childList: !0, subtree: !0 });
48
60
  }
49
61
  track(e, i, t) {
50
62
  this.isBrowser() && this.queue.push({
@@ -128,9 +140,9 @@ class o {
128
140
  return e.includes("Windows") ? "Windows" : e.includes("Mac") ? "macOS" : e.includes("Linux") ? "Linux" : e.includes("Android") ? "Android" : /iPhone|iOS/.test(e) ? "iOS" : "Other";
129
141
  }
130
142
  destroy() {
131
- this.flushInterval && clearInterval(this.flushInterval), this.observer?.disconnect(), this.intersectionObserver?.disconnect(), this.flush();
143
+ this.flushInterval && clearInterval(this.flushInterval), this.scrollFallbackListener && window.removeEventListener("scroll", this.scrollFallbackListener), this.resizeFallbackListener && window.removeEventListener("resize", this.resizeFallbackListener), this.observer?.disconnect(), this.intersectionObserver?.disconnect(), this.flush();
132
144
  }
133
145
  }
134
146
  export {
135
- o as FeedPulseTracker
147
+ l as FeedPulseTracker
136
148
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekibo/feedpulse-sdk",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "Embeddable analytics and feedback SDK for FeedPulse",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",