plugeen 0.0.18 → 0.0.20
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.cjs +22 -6
- package/dist/index.js +22 -6
- package/dist/plugeen.global.js +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -106,9 +106,10 @@ function getOrCreateSessionId() {
|
|
|
106
106
|
// src/http-client/index.ts
|
|
107
107
|
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
108
108
|
var HttpClient = class {
|
|
109
|
-
constructor(baseUrl, apiKey) {
|
|
109
|
+
constructor(baseUrl, apiKey, logger) {
|
|
110
110
|
this.baseUrl = baseUrl;
|
|
111
111
|
this.apiKey = apiKey;
|
|
112
|
+
this.logger = logger;
|
|
112
113
|
}
|
|
113
114
|
headers(method) {
|
|
114
115
|
const h = {
|
|
@@ -122,6 +123,7 @@ var HttpClient = class {
|
|
|
122
123
|
async request(path, { retries = 0, method, body, searchParams }, attempt = 0) {
|
|
123
124
|
const sufix = searchParams ? `?${new URLSearchParams(searchParams).toString()}` : "";
|
|
124
125
|
const url = `${this.baseUrl}${path}${sufix}`;
|
|
126
|
+
this.logger.log(`[${method}] ${url}`);
|
|
125
127
|
try {
|
|
126
128
|
const res = await fetch(url, {
|
|
127
129
|
method,
|
|
@@ -131,13 +133,18 @@ var HttpClient = class {
|
|
|
131
133
|
});
|
|
132
134
|
if (res.status === 401 || res.status === 404) {
|
|
133
135
|
const json = await res.json().catch(() => null);
|
|
134
|
-
|
|
136
|
+
const err = json || new Error(String(res.status));
|
|
137
|
+
this.logger.error(`[${method}] ${url} \u2192 ${res.status}`, err);
|
|
138
|
+
throw err;
|
|
135
139
|
}
|
|
136
140
|
if ((res.status >= 500 || res.status === 429) && retries > 0) {
|
|
141
|
+
this.logger.warn(
|
|
142
|
+
`[${method}] ${url} \u2192 ${res.status}, retrying (${retries} left)`
|
|
143
|
+
);
|
|
137
144
|
await delay((1 + attempt) * 1e3);
|
|
138
145
|
return this.request(
|
|
139
146
|
path,
|
|
140
|
-
{ body, retries: retries - 1, method },
|
|
147
|
+
{ body, retries: retries - 1, method, searchParams },
|
|
141
148
|
attempt + 1
|
|
142
149
|
);
|
|
143
150
|
}
|
|
@@ -145,14 +152,23 @@ var HttpClient = class {
|
|
|
145
152
|
const json = await res.json().catch(() => {
|
|
146
153
|
throw new Error("Failed to parse json");
|
|
147
154
|
});
|
|
155
|
+
this.logger.log(`[${method}] ${url} \u2192 ${res.status}`);
|
|
148
156
|
return json.data;
|
|
149
157
|
}
|
|
150
|
-
throw new Error(
|
|
158
|
+
throw new Error(`Unexpected status ${res.status}`);
|
|
151
159
|
} catch (err) {
|
|
152
160
|
if (err instanceof TypeError && retries > 0) {
|
|
161
|
+
this.logger.warn(
|
|
162
|
+
`[${method}] ${url} \u2192 network error, retrying (${retries} left)`
|
|
163
|
+
);
|
|
153
164
|
await delay(1e3);
|
|
154
|
-
return this.
|
|
165
|
+
return this.request(
|
|
166
|
+
path,
|
|
167
|
+
{ body, method, retries: retries - 1, searchParams },
|
|
168
|
+
attempt + 1
|
|
169
|
+
);
|
|
155
170
|
}
|
|
171
|
+
this.logger.error(`[${method}] ${url} \u2192`, err);
|
|
156
172
|
throw err;
|
|
157
173
|
}
|
|
158
174
|
}
|
|
@@ -528,7 +544,7 @@ function createPlugeen(apiKey, options) {
|
|
|
528
544
|
if (!apiKey) {
|
|
529
545
|
throw new TypeError("[plugeen] data-api-key is required");
|
|
530
546
|
}
|
|
531
|
-
const http = new HttpClient(resolved.apiUrl, apiKey);
|
|
547
|
+
const http = new HttpClient(resolved.apiUrl, apiKey, logger);
|
|
532
548
|
const plugeen = {
|
|
533
549
|
track: initEventsModule(http, logger).track,
|
|
534
550
|
identify: initIdentitiesModule(http, logger).identify,
|
package/dist/index.js
CHANGED
|
@@ -104,9 +104,10 @@ function getOrCreateSessionId() {
|
|
|
104
104
|
// src/http-client/index.ts
|
|
105
105
|
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
106
106
|
var HttpClient = class {
|
|
107
|
-
constructor(baseUrl, apiKey) {
|
|
107
|
+
constructor(baseUrl, apiKey, logger) {
|
|
108
108
|
this.baseUrl = baseUrl;
|
|
109
109
|
this.apiKey = apiKey;
|
|
110
|
+
this.logger = logger;
|
|
110
111
|
}
|
|
111
112
|
headers(method) {
|
|
112
113
|
const h = {
|
|
@@ -120,6 +121,7 @@ var HttpClient = class {
|
|
|
120
121
|
async request(path, { retries = 0, method, body, searchParams }, attempt = 0) {
|
|
121
122
|
const sufix = searchParams ? `?${new URLSearchParams(searchParams).toString()}` : "";
|
|
122
123
|
const url = `${this.baseUrl}${path}${sufix}`;
|
|
124
|
+
this.logger.log(`[${method}] ${url}`);
|
|
123
125
|
try {
|
|
124
126
|
const res = await fetch(url, {
|
|
125
127
|
method,
|
|
@@ -129,13 +131,18 @@ var HttpClient = class {
|
|
|
129
131
|
});
|
|
130
132
|
if (res.status === 401 || res.status === 404) {
|
|
131
133
|
const json = await res.json().catch(() => null);
|
|
132
|
-
|
|
134
|
+
const err = json || new Error(String(res.status));
|
|
135
|
+
this.logger.error(`[${method}] ${url} \u2192 ${res.status}`, err);
|
|
136
|
+
throw err;
|
|
133
137
|
}
|
|
134
138
|
if ((res.status >= 500 || res.status === 429) && retries > 0) {
|
|
139
|
+
this.logger.warn(
|
|
140
|
+
`[${method}] ${url} \u2192 ${res.status}, retrying (${retries} left)`
|
|
141
|
+
);
|
|
135
142
|
await delay((1 + attempt) * 1e3);
|
|
136
143
|
return this.request(
|
|
137
144
|
path,
|
|
138
|
-
{ body, retries: retries - 1, method },
|
|
145
|
+
{ body, retries: retries - 1, method, searchParams },
|
|
139
146
|
attempt + 1
|
|
140
147
|
);
|
|
141
148
|
}
|
|
@@ -143,14 +150,23 @@ var HttpClient = class {
|
|
|
143
150
|
const json = await res.json().catch(() => {
|
|
144
151
|
throw new Error("Failed to parse json");
|
|
145
152
|
});
|
|
153
|
+
this.logger.log(`[${method}] ${url} \u2192 ${res.status}`);
|
|
146
154
|
return json.data;
|
|
147
155
|
}
|
|
148
|
-
throw new Error(
|
|
156
|
+
throw new Error(`Unexpected status ${res.status}`);
|
|
149
157
|
} catch (err) {
|
|
150
158
|
if (err instanceof TypeError && retries > 0) {
|
|
159
|
+
this.logger.warn(
|
|
160
|
+
`[${method}] ${url} \u2192 network error, retrying (${retries} left)`
|
|
161
|
+
);
|
|
151
162
|
await delay(1e3);
|
|
152
|
-
return this.
|
|
163
|
+
return this.request(
|
|
164
|
+
path,
|
|
165
|
+
{ body, method, retries: retries - 1, searchParams },
|
|
166
|
+
attempt + 1
|
|
167
|
+
);
|
|
153
168
|
}
|
|
169
|
+
this.logger.error(`[${method}] ${url} \u2192`, err);
|
|
154
170
|
throw err;
|
|
155
171
|
}
|
|
156
172
|
}
|
|
@@ -526,7 +542,7 @@ function createPlugeen(apiKey, options) {
|
|
|
526
542
|
if (!apiKey) {
|
|
527
543
|
throw new TypeError("[plugeen] data-api-key is required");
|
|
528
544
|
}
|
|
529
|
-
const http = new HttpClient(resolved.apiUrl, apiKey);
|
|
545
|
+
const http = new HttpClient(resolved.apiUrl, apiKey, logger);
|
|
530
546
|
const plugeen = {
|
|
531
547
|
track: initEventsModule(http, logger).track,
|
|
532
548
|
identify: initIdentitiesModule(http, logger).identify,
|
package/dist/plugeen.global.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/* plugeen v0.0.
|
|
2
|
-
"use strict";var plugeen=(()=>{function
|
|
1
|
+
/* plugeen v0.0.20 | https://plugeen.app */
|
|
2
|
+
"use strict";var plugeen=(()=>{function E(){if(typeof document>"u")return null;let r=document.currentScript;if(!r){let o=document.getElementsByTagName("script");for(let i of Array.from(o))if(i.src&&(i.src.includes("/plugeen.global")||i.src.includes("/plugeen."))){r=i;break}}if(!r)return null;let e={},t=r.getAttribute("data-api-key")??void 0;e.apiUrl=r.getAttribute("data-api-url")??void 0,e.service=r.getAttribute("data-service")??void 0,e.analytics=r.getAttribute("data-analytics")==="true",e.webVitals=r.getAttribute("data-web-vitals")==="true",e.errors=r.getAttribute("data-errors")==="true";let n=r.getAttribute("data-debug");return n!==null&&(e.debug=n==="true"||n===""),Object.fromEntries(Object.entries({...e,apiKey:t}).filter(([o,i])=>i!=null&&i!==""))}function w(r){return r?{log:(...e)=>console.log("[plugeen]",...e),warn:(...e)=>console.warn("[plugeen]",...e),error:(...e)=>console.error("[plugeen]",...e)}:{log:()=>{},warn:()=>{},error:()=>{}}}function p(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let r=new Uint8Array(16);crypto.getRandomValues(r),r[6]=r[6]&15|64,r[8]=r[8]&63|128;let e=Array.from(r).map(t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,r=>{let e=Math.floor(Math.random()*16);return(r==="x"?e:e&3|8).toString(16)})}var f="plugeen_anon_id",m="plugeen_session_id",g="plugeen_session_ts";var P=18e5,c={};function I(){try{let r=localStorage.getItem(f);return r||(r=`anon_${p()}`,localStorage.setItem(f,r)),r}catch{return c[f]||(c[f]=`anon_${p()}`),c[f]}}function k(r){try{localStorage.setItem(f,r)}catch{c[f]=r}}function y(){try{let r=sessionStorage.getItem(m),e=sessionStorage.getItem(g);if(r&&e&&Date.now()-parseInt(e,10)<P)return sessionStorage.setItem(g,String(Date.now())),r;sessionStorage.removeItem(m),sessionStorage.removeItem(g);let t=`sess_${p()}`;return sessionStorage.setItem(m,t),sessionStorage.setItem(g,String(Date.now())),t}catch{let r=c[m],e=c[g];if(r&&e&&Date.now()-parseInt(e,10)<P)return c[g]=String(Date.now()),r;let t=`sess_${p()}`;return c[m]=t,c[g]=String(Date.now()),t}}var T=r=>new Promise(e=>setTimeout(e,r)),v=class{constructor(e,t,n){this.baseUrl=e;this.apiKey=t;this.logger=n}headers(e){let t={Authorization:`Bearer ${this.apiKey}`,"x-identity-id":I(),"x-session-id":y()};return e!=="GET"&&(t["Content-Type"]="application/json"),t}async request(e,{retries:t=0,method:n,body:o,searchParams:i},a=0){let u=i?`?${new URLSearchParams(i).toString()}`:"",l=`${this.baseUrl}${e}${u}`;this.logger.log(`[${n}] ${l}`);try{let s=await fetch(l,{method:n,headers:this.headers(n),credentials:"omit",body:o?JSON.stringify(o):void 0});if(s.status===401||s.status===404){let h=await s.json().catch(()=>null)||new Error(String(s.status));throw this.logger.error(`[${n}] ${l} \u2192 ${s.status}`,h),h}if((s.status>=500||s.status===429)&&t>0)return this.logger.warn(`[${n}] ${l} \u2192 ${s.status}, retrying (${t} left)`),await T((1+a)*1e3),this.request(e,{body:o,retries:t-1,method:n,searchParams:i},a+1);if(s.status>=200&&s.status<300){let d=await s.json().catch(()=>{throw new Error("Failed to parse json")});return this.logger.log(`[${n}] ${l} \u2192 ${s.status}`),d.data}throw new Error(`Unexpected status ${s.status}`)}catch(s){if(s instanceof TypeError&&t>0)return this.logger.warn(`[${n}] ${l} \u2192 network error, retrying (${t} left)`),await T(1e3),this.request(e,{body:o,method:n,retries:t-1,searchParams:i},a+1);throw this.logger.error(`[${n}] ${l} \u2192`,s),s}}async post(e,t,n){return this.request(e,{...n,retries:n?.retries??0,body:t,method:"POST"})}async get(e,t){return this.request(e,{...t,retries:t?.retries??0,method:"GET"})}beacon(e,t){if(typeof navigator>"u"||!navigator.sendBeacon)return!1;try{let n=new Blob([JSON.stringify(t)],{type:"application/json"});return navigator.sendBeacon(`${this.baseUrl}${e}`,n)}catch{return!1}}};function L(r,e){if(typeof window>"u")return;e.log("Analytics module started");let t=Date.now(),n=0,o=window.location.href,i=()=>{n++,r.post("/v1/analytics",{event:"page_view",url:window.location.href,title:document.title,sessionId:y(),referrer:document.referrer||void 0,screenWidth:window.innerWidth,screenHeight:window.innerHeight})},a=(s=!1)=>{let d={event:"page_exit",url:window.location.href,title:document.title,sessionId:y(),referrer:document.referrer||void 0,screenWidth:window.innerWidth,screenHeight:window.innerHeight,metadata:{timeOnPage:Math.round((Date.now()-t)/1e3),pageCount:n}};s?r.beacon("/v1/analytics",d):r.post("/v1/analytics",d)},u=()=>{window.location.href!==o&&(a(),t=Date.now(),o=window.location.href,i())},l=s=>{let d=history[s].bind(history);history[s]=(...h)=>{d(...h),u()}};l("pushState"),l("replaceState"),window.addEventListener("popstate",u),window.addEventListener("beforeunload",()=>a(!0)),document.addEventListener("visibilitychange",()=>document.visibilityState==="hidden"&&a(!0)),i()}var V=["chrome-extension://","moz-extension://","safari-extension://","edge-extension://"];function x(r){if(!r)return!1;let e=r.toLowerCase();return V.some(t=>e.includes(t))}function M(r,e){typeof window>"u"||(e.log("Errors module started"),window.addEventListener("error",t=>{x(t.filename)||x(t.error?.stack)||t.error===null&&t.message==="Script error."||r.post("/v1/logs",{message:t.message||"Unknown Error",level:"error",url:window.location.href,source:"client",metadata:{stack:t.error?.stack,type:t.error?.name}})}),window.addEventListener("unhandledrejection",t=>{let{reason:n}=t;if(x(n?.stack))return;let o="Unknown Error",i;n instanceof Error?(o=n.message,i=n.stack):typeof n=="string"?o=n:n!==null&&typeof n=="object"&&"message"in n&&(o=String(n.message)),r.post("/v1/logs",{message:o,url:window.location.href,source:"client",level:"error",metadata:{stack:i,type:"UnhandledRejection"}})}))}function S(){return performance.getEntriesByType("navigation")[0]?.activationStart??0}function H(){let r=performance.getEntriesByType("navigation")[0];if(r&&r.responseStart>0&&r.responseStart<performance.now())return r}function b(r,e,t){try{if(!PerformanceObserver.supportedEntryTypes.includes(r))return;let n=new PerformanceObserver(o=>{Promise.resolve().then(()=>e(o.getEntries()))});return n.observe({type:r,buffered:!0,...t??{}}),n}catch{return}}function R(r){let e=new Set;b("paint",t=>{for(let n of t)if(n.name==="first-contentful-paint"&&!e.has("first-contentful-paint")){e.add("first-contentful-paint");let o=Math.max(n.startTime-S(),0);r("first-contentful-paint",Math.round(o))}})}function D(r){let e=!1,t=b("largest-contentful-paint",o=>{if(e)return;let i=o[o.length-1];if(i){let a=Math.max(i.startTime-S(),0);r("largest-contentful-paint",Math.round(a))}});if(!t)return;let n=()=>{if(e)return;e=!0;let o=t.takeRecords();if(o.length>0){let i=o[o.length-1],a=Math.max(i.startTime-S(),0);r("largest-contentful-paint",Math.round(a))}t.disconnect()};for(let o of["keydown","click","visibilitychange"])addEventListener(o,n,{capture:!0,once:!0})}function N(r){let e=0,t=[],n=0;b("layout-shift",o=>{for(let i of o){let a=i;if(a.hadRecentInput)continue;let u=t[t.length-1],l=t[0];if(t.length>0&&u&&l&&a.startTime-u.startTime<1e3&&a.startTime-l.startTime<5e3?(e+=a.value,t.push(a)):(e=a.value,t=[a]),e>n){n=e;let s=Math.round(n*1e4)/1e4;r("cumulative-layout-shift",s)}}})}function j(r){let e=H();if(!e)return;let t=Math.max(e.responseStart-S(),0);r("time-to-first-byte",Math.round(t))}function W(r){let e=new Map,t=0;b("event",n=>{for(let o of n){let i=o;if(!i.interactionId)continue;let a=e.get(i.interactionId)??0;i.duration>a&&(e.set(i.interactionId,i.duration),i.duration>t&&(t=i.duration,r("interaction-to-next-paint",Math.round(i.duration))))}},{durationThreshold:40})}function B(r){if(typeof requestAnimationFrame>"u")return;let e=0,t=2e3,n=performance.now(),o=()=>{e++,performance.now()-n<t?requestAnimationFrame(o):r("frames-per-second",Math.round(e/t*1e3))};document.readyState==="complete"?requestAnimationFrame(o):window.addEventListener("load",()=>requestAnimationFrame(o),{once:!0})}function O(){if(!(typeof window<"u")||!(typeof PerformanceObserver<"u"))return[];let t=new Map;return R((n,o)=>t.set(n,o)),D((n,o)=>t.set(n,o)),N((n,o)=>t.set(n,o)),j((n,o)=>t.set(n,o)),W((n,o)=>t.set(n,o)),B((n,o)=>t.set(n,o)),Array.from(t).map(([n,o])=>({name:n,value:o}))}function C(r,e){e.log("Web Vitals module started"),r.post("/v1/web-vitals",{url:window.location.href,metrics:O()})}function _(r,e){return e.log("Identities module started"),{async identify(t,n){let o=await r.post("/v1/identities",{...n,id:t});return k(t),o}}}function $(r,e){return e.log("Events module started"),{track:(t,n={})=>r.post("/v1/events",{name:t,data:n,source:"sdk"})}}function F(r,e){return e.log("Feature Flags module started"),{get:t=>r.get("/v1/feature-flags",{searchParams:{key:t}})}}function U(r,e){return e.log("Logs module started"),{send:t=>r.post("/v1/logs",t)}}function A(r,e){let t={...e,apiUrl:e.apiUrl??"https://www.plugeen.app/api",debug:e.debug??!1,analytics:e.analytics??!1,webVitals:e.webVitals??!1,errors:e.errors??!1},n=w(t.debug);if(!r)throw new TypeError("[plugeen] data-api-key is required");let o=new v(t.apiUrl,r,n),i={track:$(o,n).track,identify:_(o,n).identify,featureFlags:F(o,n),logs:U(o,n)};return typeof window<"u"&&(t.analytics&&L(o,n),t.webVitals&&C(o,n),t.errors&&M(o,n)),n.log(`Running on ${typeof window>"u"?"server":"client"} side`),i}function q(){let r=E(),e=w(!!r?.debug);if(r){if(!r.apiKey)return e.warn("Data-api-key is required.")}else return e.warn("Failed to start script");e.log("Started");let t=A(r.apiKey,r);return window.plugeen=t,t}window.plugeen||q();})();
|