plugeen 0.0.12 → 0.0.14

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  'use strict';
2
2
 
3
+ // src/helpers/try-catch.ts
4
+ async function tryCatch(promise) {
5
+ try {
6
+ const result = await promise;
7
+ return [result, null];
8
+ } catch (err) {
9
+ return [null, err instanceof Error ? err : new Error(String(err))];
10
+ }
11
+ }
12
+
3
13
  // src/helpers/logger.ts
4
14
  function createLogger(debug) {
5
15
  if (!debug) {
@@ -96,10 +106,9 @@ function getOrCreateSessionId() {
96
106
  // src/http-client/index.ts
97
107
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
98
108
  var HttpClient = class {
99
- constructor(baseUrl, apiKey, maxRetries = 3) {
109
+ constructor(baseUrl, apiKey) {
100
110
  this.baseUrl = baseUrl;
101
111
  this.apiKey = apiKey;
102
- this.maxRetries = maxRetries;
103
112
  }
104
113
  headers(method) {
105
114
  const h = {
@@ -110,7 +119,7 @@ var HttpClient = class {
110
119
  if (method !== "GET") h["Content-Type"] = "application/json";
111
120
  return h;
112
121
  }
113
- async request(path, { attempt = 0, method, body, searchParams }) {
122
+ async request(path, { retries = 0, method, body, searchParams }, attempt = 0) {
114
123
  const sufix = searchParams ? `?${new URLSearchParams(searchParams).toString()}` : "";
115
124
  const url = `${this.baseUrl}${path}${sufix}`;
116
125
  try {
@@ -120,46 +129,45 @@ var HttpClient = class {
120
129
  credentials: "omit",
121
130
  body: body ? JSON.stringify(body) : void 0
122
131
  });
123
- if (res.status === 401 || res.status === 404) return [null, res.status];
124
- if ((res.status >= 500 || res.status === 429) && attempt < this.maxRetries) {
125
- const jitter = 0.85 + Math.random() * 0.3;
126
- await delay(500 * 2 ** attempt * jitter);
127
- return this.request(path, {
128
- body,
129
- attempt: attempt + 1,
130
- method
131
- });
132
+ if (res.status === 401 || res.status === 404) {
133
+ const json = await res.json().catch(() => null);
134
+ throw json || new Error(String(res.status));
135
+ }
136
+ if ((res.status >= 500 || res.status === 429) && retries > 0) {
137
+ await delay((1 + attempt) * 1e3);
138
+ return this.request(
139
+ path,
140
+ { body, retries: retries - 1, method },
141
+ attempt + 1
142
+ );
132
143
  }
133
144
  if (res.status >= 200 && res.status < 300) {
134
- try {
135
- const json = await res.json();
136
- return [json.data, null];
137
- } catch {
138
- return [null, "Failed to parse json"];
139
- }
145
+ const json = await res.json().catch(() => {
146
+ throw new Error("Failed to parse json");
147
+ });
148
+ return json.data;
140
149
  }
141
- return [null, "Error"];
150
+ throw new Error("Error");
142
151
  } catch (err) {
143
- if (err instanceof TypeError && attempt < this.maxRetries) {
144
- const jitter = 0.85 + Math.random() * 0.3;
145
- await delay(500 * 2 ** attempt * jitter);
146
- return this.get(path, {
147
- attempt: attempt + 1
148
- });
152
+ if (err instanceof TypeError && retries > 0) {
153
+ await delay(1e3);
154
+ return this.get(path, { retries: retries - 1 });
149
155
  }
150
- return [null, err];
156
+ throw err;
151
157
  }
152
158
  }
153
159
  async post(path, body, options) {
154
160
  return this.request(path, {
155
- attempt: options?.attempt ?? 0,
161
+ ...options,
162
+ retries: options?.retries ?? 0,
156
163
  body,
157
164
  method: "POST"
158
165
  });
159
166
  }
160
167
  async get(path, options) {
161
168
  return this.request(path, {
162
- attempt: options?.attempt ?? 0,
169
+ ...options,
170
+ retries: options?.retries ?? 0,
163
171
  method: "GET"
164
172
  });
165
173
  }
@@ -470,14 +478,12 @@ function initIdentitiesModule(http, logger) {
470
478
  logger.log("Identities module started");
471
479
  return {
472
480
  async identify(distinctId, data) {
473
- const res = await http.post("/v1/identities", {
474
- body: {
475
- ...data,
476
- id: distinctId
477
- }
478
- });
481
+ const result = await http.post(
482
+ "/v1/identities",
483
+ { ...data, id: distinctId }
484
+ );
479
485
  setIdentityId(distinctId);
480
- return res;
486
+ return result;
481
487
  }
482
488
  };
483
489
  }
@@ -486,9 +492,7 @@ function initIdentitiesModule(http, logger) {
486
492
  function initEventsModule(http, logger) {
487
493
  logger.log("Events module started");
488
494
  return {
489
- track: async (name, data = {}) => {
490
- return http.post("/v1/events", { name, data, source: "sdk" });
491
- }
495
+ track: (name, data = {}) => http.post("/v1/events", { name, data, source: "sdk" })
492
496
  };
493
497
  }
494
498
 
@@ -496,9 +500,9 @@ function initEventsModule(http, logger) {
496
500
  function initFeatureFlagsModule(http, logger) {
497
501
  logger.log("Feature Flags module started");
498
502
  return {
499
- get: async (name) => {
500
- return http.get(`/v1/feature-flags`, { searchParams: { key: name } });
501
- }
503
+ get: (name) => http.get(`/v1/feature-flags`, {
504
+ searchParams: { key: name }
505
+ })
502
506
  };
503
507
  }
504
508
 
@@ -543,3 +547,4 @@ function createPlugeen(apiKey, options) {
543
547
  }
544
548
 
545
549
  exports.createPlugeen = createPlugeen;
550
+ exports.tryCatch = tryCatch;
package/dist/index.d.cts CHANGED
@@ -56,26 +56,25 @@ type ClientModules = (typeof modules)[number];
56
56
  type SdkOptions = {
57
57
  apiUrl: string;
58
58
  debug: boolean;
59
- environment?: string;
60
59
  service?: string;
61
60
  } & Record<ClientModules, boolean>;
62
61
  type TrackFn = (event: string, data: Record<string, unknown>) => void;
63
- type TupleResponse<T> = Promise<[T, null] | [null, unknown]>;
62
+ type TupleResponse<T> = Promise<[T, null] | [null, Error]>;
64
63
  type EventsModule = {
65
- track<T = unknown>(name: string, data?: Record<string, unknown>): TupleResponse<T>;
64
+ track<T = unknown>(name: string, data?: Record<string, unknown>): Promise<T>;
66
65
  };
67
66
  type IdentitiesModule = {
68
- identify(distinctId: string, data?: Omit<IdentitySchema, "id">): TupleResponse<IdentitySchema>;
67
+ identify(distinctId: string, data?: Omit<IdentitySchema, "id">): Promise<IdentitySchema>;
69
68
  };
70
69
  interface FeatureFlagsModule {
71
- get(key: string): TupleResponse<FeatureFlagsSchema>;
70
+ get(key: string): Promise<FeatureFlagsSchema>;
72
71
  }
73
72
  interface LogsModule {
74
- send(payload: LogsSchema): TupleResponse<FeatureFlagsSchema>;
73
+ send(payload: LogsSchema): Promise<FeatureFlagsSchema>;
75
74
  }
76
75
  interface Plugeen {
77
76
  track: TrackFn;
78
- identify: (distinctId: string, data: Omit<IdentitySchema, "id">) => TupleResponse<IdentitySchema>;
77
+ identify: (distinctId: string, data: Omit<IdentitySchema, "id">) => Promise<IdentitySchema>;
79
78
  featureFlags: FeatureFlagsModule;
80
79
  logs: LogsModule;
81
80
  }
@@ -85,6 +84,8 @@ declare global {
85
84
  }
86
85
  }
87
86
 
87
+ declare function tryCatch<T>(promise: Promise<T>): Promise<[T, null] | [null, Error]>;
88
+
88
89
  declare function createPlugeen(apiKey: string, options: Partial<SdkOptions>): Plugeen;
89
90
 
90
- export { type AnalyticsSchema, type EventsModule, type EventsSchema, type FeatureFlagsModule, type FeatureFlagsSchema, type IdentitiesModule, type IdentitySchema, type LogsModule, type LogsSchema, type MetricName, type Plugeen, type SdkOptions, type TrackFn, type TupleResponse, type WebVitalsSchema, createPlugeen, webVitalsMetrics };
91
+ export { type AnalyticsSchema, type EventsModule, type EventsSchema, type FeatureFlagsModule, type FeatureFlagsSchema, type IdentitiesModule, type IdentitySchema, type LogsModule, type LogsSchema, type MetricName, type Plugeen, type SdkOptions, type TrackFn, type TupleResponse, type WebVitalsSchema, createPlugeen, tryCatch, webVitalsMetrics };
package/dist/index.d.ts CHANGED
@@ -56,26 +56,25 @@ type ClientModules = (typeof modules)[number];
56
56
  type SdkOptions = {
57
57
  apiUrl: string;
58
58
  debug: boolean;
59
- environment?: string;
60
59
  service?: string;
61
60
  } & Record<ClientModules, boolean>;
62
61
  type TrackFn = (event: string, data: Record<string, unknown>) => void;
63
- type TupleResponse<T> = Promise<[T, null] | [null, unknown]>;
62
+ type TupleResponse<T> = Promise<[T, null] | [null, Error]>;
64
63
  type EventsModule = {
65
- track<T = unknown>(name: string, data?: Record<string, unknown>): TupleResponse<T>;
64
+ track<T = unknown>(name: string, data?: Record<string, unknown>): Promise<T>;
66
65
  };
67
66
  type IdentitiesModule = {
68
- identify(distinctId: string, data?: Omit<IdentitySchema, "id">): TupleResponse<IdentitySchema>;
67
+ identify(distinctId: string, data?: Omit<IdentitySchema, "id">): Promise<IdentitySchema>;
69
68
  };
70
69
  interface FeatureFlagsModule {
71
- get(key: string): TupleResponse<FeatureFlagsSchema>;
70
+ get(key: string): Promise<FeatureFlagsSchema>;
72
71
  }
73
72
  interface LogsModule {
74
- send(payload: LogsSchema): TupleResponse<FeatureFlagsSchema>;
73
+ send(payload: LogsSchema): Promise<FeatureFlagsSchema>;
75
74
  }
76
75
  interface Plugeen {
77
76
  track: TrackFn;
78
- identify: (distinctId: string, data: Omit<IdentitySchema, "id">) => TupleResponse<IdentitySchema>;
77
+ identify: (distinctId: string, data: Omit<IdentitySchema, "id">) => Promise<IdentitySchema>;
79
78
  featureFlags: FeatureFlagsModule;
80
79
  logs: LogsModule;
81
80
  }
@@ -85,6 +84,8 @@ declare global {
85
84
  }
86
85
  }
87
86
 
87
+ declare function tryCatch<T>(promise: Promise<T>): Promise<[T, null] | [null, Error]>;
88
+
88
89
  declare function createPlugeen(apiKey: string, options: Partial<SdkOptions>): Plugeen;
89
90
 
90
- export { type AnalyticsSchema, type EventsModule, type EventsSchema, type FeatureFlagsModule, type FeatureFlagsSchema, type IdentitiesModule, type IdentitySchema, type LogsModule, type LogsSchema, type MetricName, type Plugeen, type SdkOptions, type TrackFn, type TupleResponse, type WebVitalsSchema, createPlugeen, webVitalsMetrics };
91
+ export { type AnalyticsSchema, type EventsModule, type EventsSchema, type FeatureFlagsModule, type FeatureFlagsSchema, type IdentitiesModule, type IdentitySchema, type LogsModule, type LogsSchema, type MetricName, type Plugeen, type SdkOptions, type TrackFn, type TupleResponse, type WebVitalsSchema, createPlugeen, tryCatch, webVitalsMetrics };
package/dist/index.js CHANGED
@@ -1,3 +1,13 @@
1
+ // src/helpers/try-catch.ts
2
+ async function tryCatch(promise) {
3
+ try {
4
+ const result = await promise;
5
+ return [result, null];
6
+ } catch (err) {
7
+ return [null, err instanceof Error ? err : new Error(String(err))];
8
+ }
9
+ }
10
+
1
11
  // src/helpers/logger.ts
2
12
  function createLogger(debug) {
3
13
  if (!debug) {
@@ -94,10 +104,9 @@ function getOrCreateSessionId() {
94
104
  // src/http-client/index.ts
95
105
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
96
106
  var HttpClient = class {
97
- constructor(baseUrl, apiKey, maxRetries = 3) {
107
+ constructor(baseUrl, apiKey) {
98
108
  this.baseUrl = baseUrl;
99
109
  this.apiKey = apiKey;
100
- this.maxRetries = maxRetries;
101
110
  }
102
111
  headers(method) {
103
112
  const h = {
@@ -108,7 +117,7 @@ var HttpClient = class {
108
117
  if (method !== "GET") h["Content-Type"] = "application/json";
109
118
  return h;
110
119
  }
111
- async request(path, { attempt = 0, method, body, searchParams }) {
120
+ async request(path, { retries = 0, method, body, searchParams }, attempt = 0) {
112
121
  const sufix = searchParams ? `?${new URLSearchParams(searchParams).toString()}` : "";
113
122
  const url = `${this.baseUrl}${path}${sufix}`;
114
123
  try {
@@ -118,46 +127,45 @@ var HttpClient = class {
118
127
  credentials: "omit",
119
128
  body: body ? JSON.stringify(body) : void 0
120
129
  });
121
- if (res.status === 401 || res.status === 404) return [null, res.status];
122
- if ((res.status >= 500 || res.status === 429) && attempt < this.maxRetries) {
123
- const jitter = 0.85 + Math.random() * 0.3;
124
- await delay(500 * 2 ** attempt * jitter);
125
- return this.request(path, {
126
- body,
127
- attempt: attempt + 1,
128
- method
129
- });
130
+ if (res.status === 401 || res.status === 404) {
131
+ const json = await res.json().catch(() => null);
132
+ throw json || new Error(String(res.status));
133
+ }
134
+ if ((res.status >= 500 || res.status === 429) && retries > 0) {
135
+ await delay((1 + attempt) * 1e3);
136
+ return this.request(
137
+ path,
138
+ { body, retries: retries - 1, method },
139
+ attempt + 1
140
+ );
130
141
  }
131
142
  if (res.status >= 200 && res.status < 300) {
132
- try {
133
- const json = await res.json();
134
- return [json.data, null];
135
- } catch {
136
- return [null, "Failed to parse json"];
137
- }
143
+ const json = await res.json().catch(() => {
144
+ throw new Error("Failed to parse json");
145
+ });
146
+ return json.data;
138
147
  }
139
- return [null, "Error"];
148
+ throw new Error("Error");
140
149
  } catch (err) {
141
- if (err instanceof TypeError && attempt < this.maxRetries) {
142
- const jitter = 0.85 + Math.random() * 0.3;
143
- await delay(500 * 2 ** attempt * jitter);
144
- return this.get(path, {
145
- attempt: attempt + 1
146
- });
150
+ if (err instanceof TypeError && retries > 0) {
151
+ await delay(1e3);
152
+ return this.get(path, { retries: retries - 1 });
147
153
  }
148
- return [null, err];
154
+ throw err;
149
155
  }
150
156
  }
151
157
  async post(path, body, options) {
152
158
  return this.request(path, {
153
- attempt: options?.attempt ?? 0,
159
+ ...options,
160
+ retries: options?.retries ?? 0,
154
161
  body,
155
162
  method: "POST"
156
163
  });
157
164
  }
158
165
  async get(path, options) {
159
166
  return this.request(path, {
160
- attempt: options?.attempt ?? 0,
167
+ ...options,
168
+ retries: options?.retries ?? 0,
161
169
  method: "GET"
162
170
  });
163
171
  }
@@ -468,14 +476,12 @@ function initIdentitiesModule(http, logger) {
468
476
  logger.log("Identities module started");
469
477
  return {
470
478
  async identify(distinctId, data) {
471
- const res = await http.post("/v1/identities", {
472
- body: {
473
- ...data,
474
- id: distinctId
475
- }
476
- });
479
+ const result = await http.post(
480
+ "/v1/identities",
481
+ { ...data, id: distinctId }
482
+ );
477
483
  setIdentityId(distinctId);
478
- return res;
484
+ return result;
479
485
  }
480
486
  };
481
487
  }
@@ -484,9 +490,7 @@ function initIdentitiesModule(http, logger) {
484
490
  function initEventsModule(http, logger) {
485
491
  logger.log("Events module started");
486
492
  return {
487
- track: async (name, data = {}) => {
488
- return http.post("/v1/events", { name, data, source: "sdk" });
489
- }
493
+ track: (name, data = {}) => http.post("/v1/events", { name, data, source: "sdk" })
490
494
  };
491
495
  }
492
496
 
@@ -494,9 +498,9 @@ function initEventsModule(http, logger) {
494
498
  function initFeatureFlagsModule(http, logger) {
495
499
  logger.log("Feature Flags module started");
496
500
  return {
497
- get: async (name) => {
498
- return http.get(`/v1/feature-flags`, { searchParams: { key: name } });
499
- }
501
+ get: (name) => http.get(`/v1/feature-flags`, {
502
+ searchParams: { key: name }
503
+ })
500
504
  };
501
505
  }
502
506
 
@@ -540,4 +544,4 @@ function createPlugeen(apiKey, options) {
540
544
  return plugeen;
541
545
  }
542
546
 
543
- export { createPlugeen };
547
+ export { createPlugeen, tryCatch };
@@ -1,2 +1,2 @@
1
1
  /* plugeen v0.1.0 | https://plugeen.app */
2
- "use strict";var plugeen=(()=>{function S(){if(typeof document>"u")return null;let e=document.currentScript;if(!e){let o=document.getElementsByTagName("script");for(let i of Array.from(o))if(i.src&&(i.src.includes("/plugeen.global")||i.src.includes("/plugeen."))){e=i;break}}if(!e)return null;let r={},t=e.getAttribute("data-api-key")??void 0;r.apiUrl=e.getAttribute("data-api-url")??e.getAttribute("data-service")??"",r.analytics=e.getAttribute("data-analytics")==="true",r.webVitals=e.getAttribute("data-web-vitals")==="true",r.errors=e.getAttribute("data-errors")==="true";let n=e.getAttribute("data-debug");return n!==null&&(r.debug=n==="true"||n===""),{apiKey:t,...r}}function h(e){return e?{log:(...r)=>console.log("[plugeen]",...r),warn:(...r)=>console.warn("[plugeen]",...r),error:(...r)=>console.error("[plugeen]",...r)}:{log:()=>{},warn:()=>{},error:()=>{}}}function f(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let r=Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("");return`${r.slice(0,8)}-${r.slice(8,12)}-${r.slice(12,16)}-${r.slice(16,20)}-${r.slice(20)}`}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let r=Math.floor(Math.random()*16);return(e==="x"?r:r&3|8).toString(16)})}var p="plugeen_anon_id",g="plugeen_session_id",d="plugeen_session_ts";var P=18e5,l={};function E(){try{let e=localStorage.getItem(p);return e||(e=`anon_${f()}`,localStorage.setItem(p,e)),e}catch{return l[p]||(l[p]=`anon_${f()}`),l[p]}}function I(e){try{localStorage.setItem(p,e)}catch{l[p]=e}}function m(){try{let e=sessionStorage.getItem(g),r=sessionStorage.getItem(d);if(e&&r&&Date.now()-parseInt(r,10)<P)return sessionStorage.setItem(d,String(Date.now())),e;sessionStorage.removeItem(g),sessionStorage.removeItem(d);let t=`sess_${f()}`;return sessionStorage.setItem(g,t),sessionStorage.setItem(d,String(Date.now())),t}catch{let e=l[g],r=l[d];if(e&&r&&Date.now()-parseInt(r,10)<P)return l[d]=String(Date.now()),e;let t=`sess_${f()}`;return l[g]=t,l[d]=String(Date.now()),t}}var k=e=>new Promise(r=>setTimeout(r,e)),w=class{constructor(r,t,n=3){this.baseUrl=r;this.apiKey=t;this.maxRetries=n}headers(r){let t={Authorization:`Bearer ${this.apiKey}`,"x-identity-id":E(),"x-session-id":m()};return r!=="GET"&&(t["Content-Type"]="application/json"),t}async request(r,{attempt:t=0,method:n,body:o,searchParams:i}){let s=i?`?${new URLSearchParams(i).toString()}`:"",u=`${this.baseUrl}${r}${s}`;try{let a=await fetch(u,{method:n,headers:this.headers(n),credentials:"omit",body:o?JSON.stringify(o):void 0});if(a.status===401||a.status===404)return[null,a.status];if((a.status>=500||a.status===429)&&t<this.maxRetries){let c=.85+Math.random()*.3;return await k(500*2**t*c),this.request(r,{body:o,attempt:t+1,method:n})}if(a.status>=200&&a.status<300)try{return[(await a.json()).data,null]}catch{return[null,"Failed to parse json"]}return[null,"Error"]}catch(a){if(a instanceof TypeError&&t<this.maxRetries){let c=.85+Math.random()*.3;return await k(500*2**t*c),this.get(r,{attempt:t+1})}return[null,a]}}async post(r,t,n){return this.request(r,{attempt:n?.attempt??0,body:t,method:"POST"})}async get(r,t){return this.request(r,{attempt:t?.attempt??0,method:"GET"})}beacon(r,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}${r}`,n)}catch{return!1}}};function T(e,r){if(typeof window>"u")return;r.log("Analytics module started");let t=Date.now(),n=0,o=window.location.href,i=()=>{n++,e.post("/v1/analytics",{event:"page_view",url:window.location.href,title:document.title,sessionId:m(),referrer:document.referrer||void 0,screenWidth:window.innerWidth,screenHeight:window.innerHeight})},s=(c=!1)=>{let y={event:"page_exit",url:window.location.href,title:document.title,sessionId:m(),referrer:document.referrer||void 0,screenWidth:window.innerWidth,screenHeight:window.innerHeight,metadata:{timeOnPage:Math.round((Date.now()-t)/1e3),pageCount:n}};c?e.beacon("/v1/analytics",y):e.post("/v1/analytics",y)},u=()=>{window.location.href!==o&&(s(),t=Date.now(),o=window.location.href,i())},a=c=>{let y=history[c].bind(history);history[c]=(...F)=>{y(...F),u()}};a("pushState"),a("replaceState"),window.addEventListener("popstate",u),window.addEventListener("beforeunload",()=>s(!0)),document.addEventListener("visibilitychange",()=>document.visibilityState==="hidden"&&s(!0)),i()}var V=["chrome-extension://","moz-extension://","safari-extension://","edge-extension://"];function v(e){if(!e)return!1;let r=e.toLowerCase();return V.some(t=>r.includes(t))}function M(e,r){typeof window>"u"||(r.log("Errors module started"),window.addEventListener("error",t=>{v(t.filename)||v(t.error?.stack)||t.error===null&&t.message==="Script error."||e.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(v(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)),e.post("/v1/logs",{message:o,url:window.location.href,source:"client",level:"error",metadata:{stack:i,type:"UnhandledRejection"}})}))}function x(){return performance.getEntriesByType("navigation")[0]?.activationStart??0}function H(){let e=performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e}function b(e,r,t){try{if(!PerformanceObserver.supportedEntryTypes.includes(e))return;let n=new PerformanceObserver(o=>{Promise.resolve().then(()=>r(o.getEntries()))});return n.observe({type:e,buffered:!0,...t??{}}),n}catch{return}}function D(e){let r=new Set;b("paint",t=>{for(let n of t)if(n.name==="first-contentful-paint"&&!r.has("first-contentful-paint")){r.add("first-contentful-paint");let o=Math.max(n.startTime-x(),0);e("first-contentful-paint",Math.round(o))}})}function N(e){let r=!1,t=b("largest-contentful-paint",o=>{if(r)return;let i=o[o.length-1];if(i){let s=Math.max(i.startTime-x(),0);e("largest-contentful-paint",Math.round(s))}});if(!t)return;let n=()=>{if(r)return;r=!0;let o=t.takeRecords();if(o.length>0){let i=o[o.length-1],s=Math.max(i.startTime-x(),0);e("largest-contentful-paint",Math.round(s))}t.disconnect()};for(let o of["keydown","click","visibilitychange"])addEventListener(o,n,{capture:!0,once:!0})}function $(e){let r=0,t=[],n=0;b("layout-shift",o=>{for(let i of o){let s=i;if(s.hadRecentInput)continue;let u=t[t.length-1],a=t[0];if(t.length>0&&u&&a&&s.startTime-u.startTime<1e3&&s.startTime-a.startTime<5e3?(r+=s.value,t.push(s)):(r=s.value,t=[s]),r>n){n=r;let c=Math.round(n*1e4)/1e4;e("cumulative-layout-shift",c)}}})}function j(e){let r=H();if(!r)return;let t=Math.max(r.responseStart-x(),0);e("time-to-first-byte",Math.round(t))}function W(e){let r=new Map,t=0;b("event",n=>{for(let o of n){let i=o;if(!i.interactionId)continue;let s=r.get(i.interactionId)??0;i.duration>s&&(r.set(i.interactionId,i.duration),i.duration>t&&(t=i.duration,e("interaction-to-next-paint",Math.round(i.duration))))}},{durationThreshold:40})}function B(e){if(typeof requestAnimationFrame>"u")return;let r=0,t=2e3,n=performance.now(),o=()=>{r++,performance.now()-n<t?requestAnimationFrame(o):e("frames-per-second",Math.round(r/t*1e3))};document.readyState==="complete"?requestAnimationFrame(o):window.addEventListener("load",()=>requestAnimationFrame(o),{once:!0})}function L(){if(!(typeof window<"u")||!(typeof PerformanceObserver<"u"))return[];let t=new Map;return D((n,o)=>t.set(n,o)),N((n,o)=>t.set(n,o)),$((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 O(e,r){r.log("Web Vitals module started"),e.post("/v1/web-vitals",{url:window.location.href,metrics:L()})}function C(e,r){return r.log("Identities module started"),{async identify(t,n){let o=await e.post("/v1/identities",{body:{...n,id:t}});return I(t),o}}}function _(e,r){return r.log("Events module started"),{track:async(t,n={})=>e.post("/v1/events",{name:t,data:n,source:"sdk"})}}function R(e,r){return r.log("Feature Flags module started"),{get:async t=>e.get("/v1/feature-flags",{searchParams:{key:t}})}}function U(e,r){return r.log("Logs module started"),{send:t=>e.post("/v1/logs",t)}}function A(e,r){let t={apiUrl:"https://dev.plugeen.app/api",debug:!1,analytics:!1,webVitals:!1,errors:!1,...r},n=h(t.debug);if(!e)throw new TypeError("[plugeen] data-api-key is required");let o=new w(t.apiUrl,e),i={track:_(o,n).track,identify:C(o,n).identify,featureFlags:R(o,n),logs:U(o,n)};return typeof window<"u"&&(t.analytics&&T(o,n),t.webVitals&&O(o,n),t.errors&&M(o,n)),n.log(`Running on ${typeof window>"u"?"server":"client"} side`),i}function q(){let e=S(),r=h(!!e?.debug);if(e){if(!e.apiKey)return r.warn("Data-api-key is required.")}else return r.warn("Failed to start script");r.log("Started");let t=A(e.apiKey,e);return window.plugeen=t,t}window.plugeen||q();})();
2
+ "use strict";var plugeen=(()=>{function b(){if(typeof document>"u")return null;let e=document.currentScript;if(!e){let o=document.getElementsByTagName("script");for(let i of Array.from(o))if(i.src&&(i.src.includes("/plugeen.global")||i.src.includes("/plugeen."))){e=i;break}}if(!e)return null;let t={},r=e.getAttribute("data-api-key")??void 0;t.apiUrl=e.getAttribute("data-api-url")??"",t.service=e.getAttribute("data-service")??"",t.analytics=e.getAttribute("data-analytics")==="true",t.webVitals=e.getAttribute("data-web-vitals")==="true",t.errors=e.getAttribute("data-errors")==="true";let n=e.getAttribute("data-debug");return n!==null&&(t.debug=n==="true"||n===""),{apiKey:r,...t}}function h(e){return e?{log:(...t)=>console.log("[plugeen]",...t),warn:(...t)=>console.warn("[plugeen]",...t),error:(...t)=>console.error("[plugeen]",...t)}:{log:()=>{},warn:()=>{},error:()=>{}}}function g(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e).map(r=>r.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.floor(Math.random()*16);return(e==="x"?t:t&3|8).toString(16)})}var f="plugeen_anon_id",m="plugeen_session_id",d="plugeen_session_ts";var P=18e5,c={};function E(){try{let e=localStorage.getItem(f);return e||(e=`anon_${g()}`,localStorage.setItem(f,e)),e}catch{return c[f]||(c[f]=`anon_${g()}`),c[f]}}function I(e){try{localStorage.setItem(f,e)}catch{c[f]=e}}function y(){try{let e=sessionStorage.getItem(m),t=sessionStorage.getItem(d);if(e&&t&&Date.now()-parseInt(t,10)<P)return sessionStorage.setItem(d,String(Date.now())),e;sessionStorage.removeItem(m),sessionStorage.removeItem(d);let r=`sess_${g()}`;return sessionStorage.setItem(m,r),sessionStorage.setItem(d,String(Date.now())),r}catch{let e=c[m],t=c[d];if(e&&t&&Date.now()-parseInt(t,10)<P)return c[d]=String(Date.now()),e;let r=`sess_${g()}`;return c[m]=r,c[d]=String(Date.now()),r}}var k=e=>new Promise(t=>setTimeout(t,e)),w=class{constructor(t,r){this.baseUrl=t;this.apiKey=r}headers(t){let r={Authorization:`Bearer ${this.apiKey}`,"x-identity-id":E(),"x-session-id":y()};return t!=="GET"&&(r["Content-Type"]="application/json"),r}async request(t,{retries:r=0,method:n,body:o,searchParams:i},s=0){let l=i?`?${new URLSearchParams(i).toString()}`:"",u=`${this.baseUrl}${t}${l}`;try{let a=await fetch(u,{method:n,headers:this.headers(n),credentials:"omit",body:o?JSON.stringify(o):void 0});if(a.status===401||a.status===404)throw await a.json().catch(()=>null)||new Error(String(a.status));if((a.status>=500||a.status===429)&&r>0)return await k((1+s)*1e3),this.request(t,{body:o,retries:r-1,method:n},s+1);if(a.status>=200&&a.status<300)return(await a.json().catch(()=>{throw new Error("Failed to parse json")})).data;throw new Error("Error")}catch(a){if(a instanceof TypeError&&r>0)return await k(1e3),this.get(t,{retries:r-1});throw a}}async post(t,r,n){return this.request(t,{...n,retries:n?.retries??0,body:r,method:"POST"})}async get(t,r){return this.request(t,{...r,retries:r?.retries??0,method:"GET"})}beacon(t,r){if(typeof navigator>"u"||!navigator.sendBeacon)return!1;try{let n=new Blob([JSON.stringify(r)],{type:"application/json"});return navigator.sendBeacon(`${this.baseUrl}${t}`,n)}catch{return!1}}};function T(e,t){if(typeof window>"u")return;t.log("Analytics module started");let r=Date.now(),n=0,o=window.location.href,i=()=>{n++,e.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})},s=(a=!1)=>{let p={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()-r)/1e3),pageCount:n}};a?e.beacon("/v1/analytics",p):e.post("/v1/analytics",p)},l=()=>{window.location.href!==o&&(s(),r=Date.now(),o=window.location.href,i())},u=a=>{let p=history[a].bind(history);history[a]=(...V)=>{p(...V),l()}};u("pushState"),u("replaceState"),window.addEventListener("popstate",l),window.addEventListener("beforeunload",()=>s(!0)),document.addEventListener("visibilitychange",()=>document.visibilityState==="hidden"&&s(!0)),i()}var H=["chrome-extension://","moz-extension://","safari-extension://","edge-extension://"];function v(e){if(!e)return!1;let t=e.toLowerCase();return H.some(r=>t.includes(r))}function M(e,t){typeof window>"u"||(t.log("Errors module started"),window.addEventListener("error",r=>{v(r.filename)||v(r.error?.stack)||r.error===null&&r.message==="Script error."||e.post("/v1/logs",{message:r.message||"Unknown Error",level:"error",url:window.location.href,source:"client",metadata:{stack:r.error?.stack,type:r.error?.name}})}),window.addEventListener("unhandledrejection",r=>{let{reason:n}=r;if(v(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)),e.post("/v1/logs",{message:o,url:window.location.href,source:"client",level:"error",metadata:{stack:i,type:"UnhandledRejection"}})}))}function x(){return performance.getEntriesByType("navigation")[0]?.activationStart??0}function R(){let e=performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e}function S(e,t,r){try{if(!PerformanceObserver.supportedEntryTypes.includes(e))return;let n=new PerformanceObserver(o=>{Promise.resolve().then(()=>t(o.getEntries()))});return n.observe({type:e,buffered:!0,...r??{}}),n}catch{return}}function D(e){let t=new Set;S("paint",r=>{for(let n of r)if(n.name==="first-contentful-paint"&&!t.has("first-contentful-paint")){t.add("first-contentful-paint");let o=Math.max(n.startTime-x(),0);e("first-contentful-paint",Math.round(o))}})}function N(e){let t=!1,r=S("largest-contentful-paint",o=>{if(t)return;let i=o[o.length-1];if(i){let s=Math.max(i.startTime-x(),0);e("largest-contentful-paint",Math.round(s))}});if(!r)return;let n=()=>{if(t)return;t=!0;let o=r.takeRecords();if(o.length>0){let i=o[o.length-1],s=Math.max(i.startTime-x(),0);e("largest-contentful-paint",Math.round(s))}r.disconnect()};for(let o of["keydown","click","visibilitychange"])addEventListener(o,n,{capture:!0,once:!0})}function $(e){let t=0,r=[],n=0;S("layout-shift",o=>{for(let i of o){let s=i;if(s.hadRecentInput)continue;let l=r[r.length-1],u=r[0];if(r.length>0&&l&&u&&s.startTime-l.startTime<1e3&&s.startTime-u.startTime<5e3?(t+=s.value,r.push(s)):(t=s.value,r=[s]),t>n){n=t;let a=Math.round(n*1e4)/1e4;e("cumulative-layout-shift",a)}}})}function j(e){let t=R();if(!t)return;let r=Math.max(t.responseStart-x(),0);e("time-to-first-byte",Math.round(r))}function W(e){let t=new Map,r=0;S("event",n=>{for(let o of n){let i=o;if(!i.interactionId)continue;let s=t.get(i.interactionId)??0;i.duration>s&&(t.set(i.interactionId,i.duration),i.duration>r&&(r=i.duration,e("interaction-to-next-paint",Math.round(i.duration))))}},{durationThreshold:40})}function B(e){if(typeof requestAnimationFrame>"u")return;let t=0,r=2e3,n=performance.now(),o=()=>{t++,performance.now()-n<r?requestAnimationFrame(o):e("frames-per-second",Math.round(t/r*1e3))};document.readyState==="complete"?requestAnimationFrame(o):window.addEventListener("load",()=>requestAnimationFrame(o),{once:!0})}function L(){if(!(typeof window<"u")||!(typeof PerformanceObserver<"u"))return[];let r=new Map;return D((n,o)=>r.set(n,o)),N((n,o)=>r.set(n,o)),$((n,o)=>r.set(n,o)),j((n,o)=>r.set(n,o)),W((n,o)=>r.set(n,o)),B((n,o)=>r.set(n,o)),Array.from(r).map(([n,o])=>({name:n,value:o}))}function C(e,t){t.log("Web Vitals module started"),e.post("/v1/web-vitals",{url:window.location.href,metrics:L()})}function O(e,t){return t.log("Identities module started"),{async identify(r,n){let o=await e.post("/v1/identities",{...n,id:r});return I(r),o}}}function _(e,t){return t.log("Events module started"),{track:(r,n={})=>e.post("/v1/events",{name:r,data:n,source:"sdk"})}}function F(e,t){return t.log("Feature Flags module started"),{get:r=>e.get("/v1/feature-flags",{searchParams:{key:r}})}}function U(e,t){return t.log("Logs module started"),{send:r=>e.post("/v1/logs",r)}}function A(e,t){let r={apiUrl:"https://dev.plugeen.app/api",debug:!1,analytics:!1,webVitals:!1,errors:!1,...t},n=h(r.debug);if(!e)throw new TypeError("[plugeen] data-api-key is required");let o=new w(r.apiUrl,e),i={track:_(o,n).track,identify:O(o,n).identify,featureFlags:F(o,n),logs:U(o,n)};return typeof window<"u"&&(r.analytics&&T(o,n),r.webVitals&&C(o,n),r.errors&&M(o,n)),n.log(`Running on ${typeof window>"u"?"server":"client"} side`),i}function q(){let e=b(),t=h(!!e?.debug);if(e){if(!e.apiKey)return t.warn("Data-api-key is required.")}else return t.warn("Failed to start script");t.log("Started");let r=A(e.apiKey,e);return window.plugeen=r,r}window.plugeen||q();})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plugeen",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "main": "./dist/index.cjs",
5
5
  "module": "./dist/index.js",
6
6
  "devDependencies": {