@senzops/web 1.1.0 → 1.2.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.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.global.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/index.ts +63 -24
package/dist/index.d.mts
CHANGED
|
@@ -9,7 +9,9 @@ declare class SenzorWebAgent {
|
|
|
9
9
|
private initialized;
|
|
10
10
|
constructor();
|
|
11
11
|
init(config: Config): void;
|
|
12
|
-
private
|
|
12
|
+
private normalizeUrl;
|
|
13
|
+
private manageSession;
|
|
14
|
+
private determineReferrer;
|
|
13
15
|
private getIds;
|
|
14
16
|
private trackPageView;
|
|
15
17
|
private trackPing;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ declare class SenzorWebAgent {
|
|
|
9
9
|
private initialized;
|
|
10
10
|
constructor();
|
|
11
11
|
init(config: Config): void;
|
|
12
|
-
private
|
|
12
|
+
private normalizeUrl;
|
|
13
|
+
private manageSession;
|
|
14
|
+
private determineReferrer;
|
|
13
15
|
private getIds;
|
|
14
16
|
private trackPageView;
|
|
15
17
|
private trackPing;
|
package/dist/index.global.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function
|
|
1
|
+
(()=>{function d(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,a=>{let e=Math.random()*16|0;return(a==="x"?e:e&3|8).toString(16)})}var o=class{config;startTime;endpoint;initialized;constructor(){this.config={webId:"",endpoint:"https://api.senzor.dev/api/ingest/web"},this.startTime=Date.now(),this.endpoint="",this.initialized=!1}init(e){if(this.initialized){console.warn("[Senzor] Agent already initialized.");return}if(this.initialized=!0,this.config={...this.config,...e},this.endpoint=this.config.endpoint||"https://api.senzor.dev/api/ingest/web",!this.config.webId){console.error("[Senzor] WebId is required.");return}this.manageSession(),this.trackPageView(),this.setupListeners()}normalizeUrl(e){return e?e.replace(/^https?:\/\//,""):""}manageSession(){let e=Date.now(),t=parseInt(localStorage.getItem("senzor_last_activity")||"0",10),r=1800*1e3;localStorage.getItem("senzor_vid")||localStorage.setItem("senzor_vid",d());let i=sessionStorage.getItem("senzor_sid"),n=e-t>r;!i||n?(i=d(),sessionStorage.setItem("senzor_sid",i),this.determineReferrer(!0)):this.determineReferrer(!1),localStorage.setItem("senzor_last_activity",e.toString())}determineReferrer(e){let t=document.referrer,r=window.location.hostname,i=sessionStorage.getItem("senzor_ref"),n=!1;if(t)try{new URL(t).hostname!==r&&(n=!0)}catch{n=!0}if(n){let s=this.normalizeUrl(t);s!==i&&sessionStorage.setItem("senzor_ref",s)}else e&&!i&&sessionStorage.setItem("senzor_ref","Direct")}getIds(){return localStorage.setItem("senzor_last_activity",Date.now().toString()),{visitorId:localStorage.getItem("senzor_vid")||"unknown",sessionId:sessionStorage.getItem("senzor_sid")||"unknown",referrer:sessionStorage.getItem("senzor_ref")||"Direct"}}trackPageView(){this.manageSession(),this.startTime=Date.now();let e={type:"pageview",webId:this.config.webId,...this.getIds(),url:window.location.href,path:window.location.pathname,title:document.title,width:window.innerWidth,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,referrer:this.getIds().referrer};this.send(e)}trackPing(){let e=Math.floor((Date.now()-this.startTime)/1e3);if(e<1)return;let t={type:"ping",webId:this.config.webId,...this.getIds(),url:window.location.href,path:window.location.pathname,title:document.title,width:window.innerWidth,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,referrer:this.getIds().referrer,duration:e};this.send(t)}send(e){if(navigator.sendBeacon){let t=new Blob([JSON.stringify(e)],{type:"application/json"});navigator.sendBeacon(this.endpoint,t)||this.fallbackSend(e)}else this.fallbackSend(e)}fallbackSend(e){fetch(this.endpoint,{method:"POST",body:JSON.stringify(e),keepalive:!0,headers:{"Content-Type":"application/json"}}).catch(t=>console.error("[Senzor] Telemetry Error:",t))}setupListeners(){let e=history.pushState;history.pushState=(...t)=>{this.trackPing(),e.apply(history,t),this.trackPageView()},window.addEventListener("popstate",()=>{this.trackPing(),this.trackPageView()}),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?this.trackPing():(this.startTime=Date.now(),this.manageSession())}),window.addEventListener("beforeunload",()=>{this.trackPing()})}},c=new o;typeof window<"u"&&(window.Senzor=c);})();
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var a=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var f=(n,e)=>{for(var t in e)a(n,t,{get:e[t],enumerable:!0})},w=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of h(e))!p.call(n,i)&&i!==t&&a(n,i,{get:()=>e[i],enumerable:!(r=g(e,i))||r.enumerable});return n};var m=n=>w(a({},"__esModule",{value:!0}),n);var u={};f(u,{Senzor:()=>l});module.exports=m(u);function c(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)})}var d=class{config;startTime;endpoint;initialized;constructor(){this.config={webId:"",endpoint:"https://api.senzor.dev/api/ingest/web"},this.startTime=Date.now(),this.endpoint="",this.initialized=!1}init(e){if(this.initialized){console.warn("[Senzor] Agent already initialized.");return}if(this.initialized=!0,this.config={...this.config,...e},this.endpoint=this.config.endpoint||"https://api.senzor.dev/api/ingest/web",!this.config.webId){console.error("[Senzor] WebId is required.");return}this.manageSession(),this.trackPageView(),this.setupListeners()}normalizeUrl(e){return e?e.replace(/^https?:\/\//,""):""}manageSession(){let e=Date.now(),t=parseInt(localStorage.getItem("senzor_last_activity")||"0",10),r=1800*1e3;localStorage.getItem("senzor_vid")||localStorage.setItem("senzor_vid",c());let i=sessionStorage.getItem("senzor_sid"),s=e-t>r;!i||s?(i=c(),sessionStorage.setItem("senzor_sid",i),this.determineReferrer(!0)):this.determineReferrer(!1),localStorage.setItem("senzor_last_activity",e.toString())}determineReferrer(e){let t=document.referrer,r=window.location.hostname,i=sessionStorage.getItem("senzor_ref"),s=!1;if(t)try{new URL(t).hostname!==r&&(s=!0)}catch{s=!0}if(s){let o=this.normalizeUrl(t);o!==i&&sessionStorage.setItem("senzor_ref",o)}else e&&!i&&sessionStorage.setItem("senzor_ref","Direct")}getIds(){return localStorage.setItem("senzor_last_activity",Date.now().toString()),{visitorId:localStorage.getItem("senzor_vid")||"unknown",sessionId:sessionStorage.getItem("senzor_sid")||"unknown",referrer:sessionStorage.getItem("senzor_ref")||"Direct"}}trackPageView(){this.manageSession(),this.startTime=Date.now();let e={type:"pageview",webId:this.config.webId,...this.getIds(),url:window.location.href,path:window.location.pathname,title:document.title,width:window.innerWidth,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,referrer:this.getIds().referrer};this.send(e)}trackPing(){let e=Math.floor((Date.now()-this.startTime)/1e3);if(e<1)return;let t={type:"ping",webId:this.config.webId,...this.getIds(),url:window.location.href,path:window.location.pathname,title:document.title,width:window.innerWidth,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,referrer:this.getIds().referrer,duration:e};this.send(t)}send(e){if(navigator.sendBeacon){let t=new Blob([JSON.stringify(e)],{type:"application/json"});navigator.sendBeacon(this.endpoint,t)||this.fallbackSend(e)}else this.fallbackSend(e)}fallbackSend(e){fetch(this.endpoint,{method:"POST",body:JSON.stringify(e),keepalive:!0,headers:{"Content-Type":"application/json"}}).catch(t=>console.error("[Senzor] Telemetry Error:",t))}setupListeners(){let e=history.pushState;history.pushState=(...t)=>{this.trackPing(),e.apply(history,t),this.trackPageView()},window.addEventListener("popstate",()=>{this.trackPing(),this.trackPageView()}),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?this.trackPing():(this.startTime=Date.now(),this.manageSession())}),window.addEventListener("beforeunload",()=>{this.trackPing()})}},l=new d;typeof window<"u"&&(window.Senzor=l);0&&(module.exports={Senzor});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function d(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,a=>{let e=Math.random()*16|0;return(a==="x"?e:e&3|8).toString(16)})}var o=class{config;startTime;endpoint;initialized;constructor(){this.config={webId:"",endpoint:"https://api.senzor.dev/api/ingest/web"},this.startTime=Date.now(),this.endpoint="",this.initialized=!1}init(e){if(this.initialized){console.warn("[Senzor] Agent already initialized.");return}if(this.initialized=!0,this.config={...this.config,...e},this.endpoint=this.config.endpoint||"https://api.senzor.dev/api/ingest/web",!this.config.webId){console.error("[Senzor] WebId is required.");return}this.manageSession(),this.trackPageView(),this.setupListeners()}normalizeUrl(e){return e?e.replace(/^https?:\/\//,""):""}manageSession(){let e=Date.now(),t=parseInt(localStorage.getItem("senzor_last_activity")||"0",10),r=1800*1e3;localStorage.getItem("senzor_vid")||localStorage.setItem("senzor_vid",d());let i=sessionStorage.getItem("senzor_sid"),n=e-t>r;!i||n?(i=d(),sessionStorage.setItem("senzor_sid",i),this.determineReferrer(!0)):this.determineReferrer(!1),localStorage.setItem("senzor_last_activity",e.toString())}determineReferrer(e){let t=document.referrer,r=window.location.hostname,i=sessionStorage.getItem("senzor_ref"),n=!1;if(t)try{new URL(t).hostname!==r&&(n=!0)}catch{n=!0}if(n){let s=this.normalizeUrl(t);s!==i&&sessionStorage.setItem("senzor_ref",s)}else e&&!i&&sessionStorage.setItem("senzor_ref","Direct")}getIds(){return localStorage.setItem("senzor_last_activity",Date.now().toString()),{visitorId:localStorage.getItem("senzor_vid")||"unknown",sessionId:sessionStorage.getItem("senzor_sid")||"unknown",referrer:sessionStorage.getItem("senzor_ref")||"Direct"}}trackPageView(){this.manageSession(),this.startTime=Date.now();let e={type:"pageview",webId:this.config.webId,...this.getIds(),url:window.location.href,path:window.location.pathname,title:document.title,width:window.innerWidth,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,referrer:this.getIds().referrer};this.send(e)}trackPing(){let e=Math.floor((Date.now()-this.startTime)/1e3);if(e<1)return;let t={type:"ping",webId:this.config.webId,...this.getIds(),url:window.location.href,path:window.location.pathname,title:document.title,width:window.innerWidth,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,referrer:this.getIds().referrer,duration:e};this.send(t)}send(e){if(navigator.sendBeacon){let t=new Blob([JSON.stringify(e)],{type:"application/json"});navigator.sendBeacon(this.endpoint,t)||this.fallbackSend(e)}else this.fallbackSend(e)}fallbackSend(e){fetch(this.endpoint,{method:"POST",body:JSON.stringify(e),keepalive:!0,headers:{"Content-Type":"application/json"}}).catch(t=>console.error("[Senzor] Telemetry Error:",t))}setupListeners(){let e=history.pushState;history.pushState=(...t)=>{this.trackPing(),e.apply(history,t),this.trackPageView()},window.addEventListener("popstate",()=>{this.trackPing(),this.trackPageView()}),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?this.trackPing():(this.startTime=Date.now(),this.manageSession())}),window.addEventListener("beforeunload",()=>{this.trackPing()})}},c=new o;typeof window<"u"&&(window.Senzor=c);export{c as Senzor};
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ interface Payload {
|
|
|
10
10
|
sessionId: string;
|
|
11
11
|
url: string;
|
|
12
12
|
path: string;
|
|
13
|
+
title: string;
|
|
13
14
|
referrer: string;
|
|
14
15
|
width: number;
|
|
15
16
|
timezone: string;
|
|
@@ -56,50 +57,86 @@ class SenzorWebAgent {
|
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
this.checkSession();
|
|
61
|
-
|
|
62
|
-
// 2. Track initial load
|
|
60
|
+
this.manageSession();
|
|
63
61
|
this.trackPageView();
|
|
64
|
-
|
|
65
|
-
// 3. Setup Listeners
|
|
66
62
|
this.setupListeners();
|
|
67
63
|
}
|
|
68
64
|
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
// Helper to normalize referrer (strip protocol)
|
|
66
|
+
private normalizeUrl(url: string): string {
|
|
67
|
+
if (!url) return '';
|
|
68
|
+
return url.replace(/^https?:\/\//, '');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private manageSession() {
|
|
72
72
|
const now = Date.now();
|
|
73
73
|
const lastActivity = parseInt(localStorage.getItem('senzor_last_activity') || '0', 10);
|
|
74
74
|
const sessionTimeout = 30 * 60 * 1000; // 30 mins
|
|
75
75
|
|
|
76
|
-
//
|
|
76
|
+
// Visitor ID (Persistent 1 Year)
|
|
77
77
|
if (!localStorage.getItem('senzor_vid')) {
|
|
78
78
|
localStorage.setItem('senzor_vid', generateUUID());
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
// Session ID
|
|
82
|
+
let sessionId = sessionStorage.getItem('senzor_sid');
|
|
83
|
+
const isExpired = (now - lastActivity > sessionTimeout);
|
|
84
|
+
|
|
85
|
+
// Session logic
|
|
86
|
+
if (!sessionId || isExpired) {
|
|
87
|
+
sessionId = generateUUID();
|
|
88
|
+
sessionStorage.setItem('senzor_sid', sessionId);
|
|
89
|
+
this.determineReferrer(true);
|
|
90
|
+
} else {
|
|
91
|
+
// Ongoing session: Check if external source changed
|
|
92
|
+
this.determineReferrer(false);
|
|
85
93
|
}
|
|
86
94
|
|
|
87
|
-
// Update Activity
|
|
88
95
|
localStorage.setItem('senzor_last_activity', now.toString());
|
|
89
96
|
}
|
|
90
97
|
|
|
98
|
+
private determineReferrer(isNewSession: boolean) {
|
|
99
|
+
const rawReferrer = document.referrer;
|
|
100
|
+
const currentHost = window.location.hostname;
|
|
101
|
+
let storedReferrer = sessionStorage.getItem('senzor_ref');
|
|
102
|
+
|
|
103
|
+
let isExternal = false;
|
|
104
|
+
if (rawReferrer) {
|
|
105
|
+
try {
|
|
106
|
+
const refUrl = new URL(rawReferrer);
|
|
107
|
+
// Compare hosts
|
|
108
|
+
if (refUrl.hostname !== currentHost) {
|
|
109
|
+
isExternal = true;
|
|
110
|
+
}
|
|
111
|
+
} catch (e) {
|
|
112
|
+
isExternal = true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (isExternal) {
|
|
117
|
+
// Always overwrite if it's a new external source
|
|
118
|
+
const cleanRef = this.normalizeUrl(rawReferrer);
|
|
119
|
+
// Only update if different to avoid redundant writes
|
|
120
|
+
if (cleanRef !== storedReferrer) {
|
|
121
|
+
sessionStorage.setItem('senzor_ref', cleanRef);
|
|
122
|
+
}
|
|
123
|
+
} else if (isNewSession && !storedReferrer) {
|
|
124
|
+
// New session with internal/no referrer = Direct
|
|
125
|
+
sessionStorage.setItem('senzor_ref', 'Direct');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
91
129
|
private getIds() {
|
|
92
|
-
// Refresh activity timestamp on every hit
|
|
93
130
|
localStorage.setItem('senzor_last_activity', Date.now().toString());
|
|
94
131
|
return {
|
|
95
132
|
visitorId: localStorage.getItem('senzor_vid') || 'unknown',
|
|
96
|
-
sessionId:
|
|
133
|
+
sessionId: sessionStorage.getItem('senzor_sid') || 'unknown',
|
|
134
|
+
referrer: sessionStorage.getItem('senzor_ref') || 'Direct'
|
|
97
135
|
};
|
|
98
136
|
}
|
|
99
137
|
|
|
100
138
|
private trackPageView() {
|
|
101
|
-
|
|
102
|
-
this.checkSession();
|
|
139
|
+
this.manageSession();
|
|
103
140
|
this.startTime = Date.now();
|
|
104
141
|
|
|
105
142
|
const payload: Payload = {
|
|
@@ -108,9 +145,10 @@ class SenzorWebAgent {
|
|
|
108
145
|
...this.getIds(),
|
|
109
146
|
url: window.location.href,
|
|
110
147
|
path: window.location.pathname,
|
|
111
|
-
|
|
148
|
+
title: document.title,
|
|
112
149
|
width: window.innerWidth,
|
|
113
150
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
151
|
+
referrer: this.getIds().referrer
|
|
114
152
|
};
|
|
115
153
|
|
|
116
154
|
this.send(payload);
|
|
@@ -126,9 +164,10 @@ class SenzorWebAgent {
|
|
|
126
164
|
...this.getIds(),
|
|
127
165
|
url: window.location.href,
|
|
128
166
|
path: window.location.pathname,
|
|
129
|
-
|
|
167
|
+
title: document.title,
|
|
130
168
|
width: window.innerWidth,
|
|
131
169
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
170
|
+
referrer: this.getIds().referrer,
|
|
132
171
|
duration: duration
|
|
133
172
|
};
|
|
134
173
|
|
|
@@ -158,9 +197,9 @@ class SenzorWebAgent {
|
|
|
158
197
|
// SPA Support
|
|
159
198
|
const originalPushState = history.pushState;
|
|
160
199
|
history.pushState = (...args) => {
|
|
161
|
-
this.trackPing();
|
|
200
|
+
this.trackPing();
|
|
162
201
|
originalPushState.apply(history, args);
|
|
163
|
-
this.trackPageView();
|
|
202
|
+
this.trackPageView();
|
|
164
203
|
};
|
|
165
204
|
|
|
166
205
|
window.addEventListener('popstate', () => {
|
|
@@ -175,7 +214,7 @@ class SenzorWebAgent {
|
|
|
175
214
|
} else {
|
|
176
215
|
// User returned, restart timer (don't count background time)
|
|
177
216
|
this.startTime = Date.now();
|
|
178
|
-
this.
|
|
217
|
+
this.manageSession();
|
|
179
218
|
}
|
|
180
219
|
});
|
|
181
220
|
|