plugeen 0.0.8 → 0.0.10

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,23 @@
1
1
  'use strict';
2
2
 
3
+ // src/helpers/logger.ts
4
+ function createLogger(debug) {
5
+ if (!debug) {
6
+ return { log: () => {
7
+ }, warn: () => {
8
+ }, error: () => {
9
+ } };
10
+ }
11
+ return {
12
+ // biome-ignore lint/suspicious/noConsole: Required
13
+ log: (...args) => console.log("[plugeen]", ...args),
14
+ // biome-ignore lint/suspicious/noConsole: Required
15
+ warn: (...args) => console.warn("[plugeen]", ...args),
16
+ // biome-ignore lint/suspicious/noConsole: Required
17
+ error: (...args) => console.error("[plugeen]", ...args)
18
+ };
19
+ }
20
+
3
21
  // src/helpers/uuid.ts
4
22
  function generateUUID() {
5
23
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
@@ -19,11 +37,12 @@ function generateUUID() {
19
37
  });
20
38
  }
21
39
 
22
- // src/storage.ts
40
+ // src/storage/index.ts
23
41
  var IDENTITY_KEY = "plugeen_anon_id";
24
42
  var SESSION_KEY = "plugeen_session_id";
25
43
  var SESSION_TS_KEY = "plugeen_session_ts";
26
44
  var SESSION_TTL = 18e5;
45
+ var memStore = {};
27
46
  function getOrCreateIdentityId() {
28
47
  try {
29
48
  let id = localStorage.getItem(IDENTITY_KEY);
@@ -33,13 +52,17 @@ function getOrCreateIdentityId() {
33
52
  }
34
53
  return id;
35
54
  } catch {
36
- return `anon_${generateUUID()}`;
55
+ if (!memStore[IDENTITY_KEY]) {
56
+ memStore[IDENTITY_KEY] = `anon_${generateUUID()}`;
57
+ }
58
+ return memStore[IDENTITY_KEY];
37
59
  }
38
60
  }
39
61
  function setIdentityId(id) {
40
62
  try {
41
63
  localStorage.setItem(IDENTITY_KEY, id);
42
64
  } catch {
65
+ memStore[IDENTITY_KEY] = id;
43
66
  }
44
67
  }
45
68
  function getOrCreateSessionId() {
@@ -57,19 +80,28 @@ function getOrCreateSessionId() {
57
80
  sessionStorage.setItem(SESSION_TS_KEY, String(Date.now()));
58
81
  return id;
59
82
  } catch {
60
- return `sess_${generateUUID()}`;
83
+ const existing = memStore[SESSION_KEY];
84
+ const ts = memStore[SESSION_TS_KEY];
85
+ if (existing && ts && Date.now() - parseInt(ts, 10) < SESSION_TTL) {
86
+ memStore[SESSION_TS_KEY] = String(Date.now());
87
+ return existing;
88
+ }
89
+ const id = `sess_${generateUUID()}`;
90
+ memStore[SESSION_KEY] = id;
91
+ memStore[SESSION_TS_KEY] = String(Date.now());
92
+ return id;
61
93
  }
62
94
  }
63
95
 
64
- // src/helpers/http-client.ts
96
+ // src/http-client/index.ts
65
97
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
66
98
  var HttpClient = class {
67
- constructor(apiUrl, apiKey, maxRetries = 3) {
68
- this.apiUrl = apiUrl;
99
+ constructor(baseUrl, apiKey, maxRetries = 3) {
100
+ this.baseUrl = baseUrl;
69
101
  this.apiKey = apiKey;
70
102
  this.maxRetries = maxRetries;
71
103
  }
72
- headers(method = "POST") {
104
+ headers(method) {
73
105
  const h = {
74
106
  Authorization: `Bearer ${this.apiKey}`,
75
107
  "x-identity-id": getOrCreateIdentityId(),
@@ -78,71 +110,58 @@ var HttpClient = class {
78
110
  if (method !== "GET") h["Content-Type"] = "application/json";
79
111
  return h;
80
112
  }
81
- async post(path, body, attempt = 0) {
82
- const url = `${this.apiUrl}${path}`;
113
+ async request(path, { attempt = 0, method, body, searchParams }) {
114
+ const sufix = searchParams ? `?${new URLSearchParams(searchParams).toString()}` : "";
115
+ const url = `${this.baseUrl}${path}${sufix}`;
83
116
  try {
84
117
  const res = await fetch(url, {
85
- method: "POST",
86
- headers: this.headers("POST"),
87
- body: JSON.stringify(body),
88
- keepalive: true,
89
- credentials: "omit"
118
+ method,
119
+ headers: this.headers(method),
120
+ credentials: "omit",
121
+ body: body ? JSON.stringify(body) : void 0
90
122
  });
91
- if (res.status === 401) return null;
123
+ if (res.status === 401 || res.status === 404) return [null, res.status];
92
124
  if ((res.status >= 500 || res.status === 429) && attempt < this.maxRetries) {
93
125
  const jitter = 0.85 + Math.random() * 0.3;
94
126
  await delay(500 * 2 ** attempt * jitter);
95
- return this.post(path, body, attempt + 1);
127
+ return this.request(path, {
128
+ body,
129
+ attempt: attempt + 1,
130
+ method
131
+ });
96
132
  }
97
133
  if (res.status >= 200 && res.status < 300) {
98
134
  try {
99
135
  const json = await res.json();
100
- return json?.data ?? null;
136
+ return [json.data, null];
101
137
  } catch {
102
- return null;
138
+ return [null, "Failed to parse json"];
103
139
  }
104
140
  }
105
- return null;
141
+ return [null, "Error"];
106
142
  } catch (err) {
107
143
  if (err instanceof TypeError && attempt < this.maxRetries) {
108
144
  const jitter = 0.85 + Math.random() * 0.3;
109
145
  await delay(500 * 2 ** attempt * jitter);
110
- return this.post(path, body, attempt + 1);
146
+ return this.get(path, {
147
+ attempt: attempt + 1
148
+ });
111
149
  }
112
- return null;
150
+ return [null, err];
113
151
  }
114
152
  }
115
- async get(path, attempt = 0) {
116
- const url = `${this.apiUrl}${path}`;
117
- try {
118
- const res = await fetch(url, {
119
- method: "GET",
120
- headers: this.headers("GET"),
121
- credentials: "omit"
122
- });
123
- if (res.status === 401 || res.status === 404) return null;
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.get(path, attempt + 1);
128
- }
129
- if (res.status >= 200 && res.status < 300) {
130
- try {
131
- const json = await res.json();
132
- return json?.data ?? null;
133
- } catch {
134
- return null;
135
- }
136
- }
137
- return null;
138
- } catch (err) {
139
- if (err instanceof TypeError && attempt < this.maxRetries) {
140
- const jitter = 0.85 + Math.random() * 0.3;
141
- await delay(500 * 2 ** attempt * jitter);
142
- return this.get(path, attempt + 1);
143
- }
144
- return null;
145
- }
153
+ async post(path, body, options) {
154
+ return this.request(path, {
155
+ attempt: options?.attempt ?? 0,
156
+ body,
157
+ method: "POST"
158
+ });
159
+ }
160
+ async get(path, options) {
161
+ return this.request(path, {
162
+ attempt: options?.attempt ?? 0,
163
+ method: "GET"
164
+ });
146
165
  }
147
166
  beacon(path, body) {
148
167
  if (typeof navigator === "undefined" || !navigator.sendBeacon) return false;
@@ -150,158 +169,23 @@ var HttpClient = class {
150
169
  const blob = new Blob([JSON.stringify(body)], {
151
170
  type: "application/json"
152
171
  });
153
- return navigator.sendBeacon(`${this.apiUrl}${path}`, blob);
172
+ return navigator.sendBeacon(`${this.baseUrl}${path}`, blob);
154
173
  } catch {
155
174
  return false;
156
175
  }
157
176
  }
158
- send(path, body, useBeacon = false) {
159
- if (useBeacon) {
160
- const sent = this.beacon(path, body);
161
- if (sent) return;
162
- }
163
- void this.post(path, body);
164
- }
165
177
  };
166
178
 
167
- // src/helpers/environment.ts
168
- function isLocalhost() {
169
- if (typeof window === "undefined") return false;
170
- const { hostname } = window.location;
171
- return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "0.0.0.0" || hostname.endsWith(".local");
172
- }
173
- function isOptedOut() {
174
- try {
175
- return localStorage.getItem("plugeen_opt_out") === "true";
176
- } catch {
177
- return false;
178
- }
179
- }
180
- function detectBot() {
181
- if (typeof navigator === "undefined") return false;
182
- const ua = navigator.userAgent || "";
183
- return Boolean(
184
- navigator.webdriver || /HeadlessChrome/i.test(ua) || /PhantomJS/i.test(ua) || typeof window !== "undefined" && window._phantom
185
- );
186
- }
187
-
188
- // src/helpers/should-skip.ts
189
- function matchesSkipPattern(patterns) {
190
- if (patterns.length === 0 || typeof window === "undefined") return false;
191
- const path = window.location.pathname;
192
- for (const pattern of patterns) {
193
- if (pattern === path) return true;
194
- const star = pattern.indexOf("*");
195
- if (star !== -1 && path.startsWith(pattern.slice(0, star))) return true;
196
- }
197
- return false;
198
- }
199
- function shouldSkip(options) {
200
- if (options.disabled) return true;
201
- if (isOptedOut()) return true;
202
- if (detectBot()) return true;
203
- if (!options.debug && isLocalhost()) return true;
204
- if (matchesSkipPattern(options.skipPatterns)) return true;
205
- if (options.samplingRate < 1 && Math.random() > options.samplingRate)
206
- return true;
207
- return false;
208
- }
209
-
210
- // src/modules/events.ts
211
- function createEventsModule(http, options) {
212
- return {
213
- create: async (name, data = {}) => {
214
- if (shouldSkip(options)) return null;
215
- return http.post("/api/events", { name, data, source: "api" });
216
- }
217
- };
218
- }
219
-
220
- // src/modules/experiments.ts
221
- function createExperimentsModule(http, options) {
222
- return {
223
- get: (id) => {
224
- if (shouldSkip(options)) return Promise.resolve(null);
225
- return http.get(
226
- `/api/v1/experiments/${encodeURIComponent(id)}`
227
- );
228
- }
229
- };
230
- }
231
-
232
- // src/modules/feature-flags.ts
233
- function createFeatureFlagsModule(http, options) {
234
- return {
235
- get: (key) => {
236
- if (shouldSkip(options)) return Promise.resolve(null);
237
- return http.get(
238
- `/api/v1/feature-flags/${encodeURIComponent(key)}`
239
- );
240
- }
241
- };
242
- }
243
-
244
- // src/modules/identities.ts
245
- function createIdentitiesModule(http, options) {
246
- return {
247
- set: async (distinctId, data = {}) => {
248
- if (shouldSkip(options)) return null;
249
- const result = await http.post("/api/identities", {
250
- id: distinctId,
251
- ...data
252
- });
253
- setIdentityId(distinctId);
254
- return result;
255
- }
256
- };
257
- }
258
-
259
- // src/modules/logs.ts
260
- function createLogsModule(http, options) {
261
- return {
262
- send: (payload) => {
263
- if (shouldSkip(options)) return Promise.resolve(null);
264
- return http.post("/api/v1/logs", payload);
265
- }
266
- };
267
- }
268
-
269
- // src/modules/surveys.ts
270
- function createSurveysModule(http, options) {
271
- return {
272
- submit: (payload) => {
273
- if (shouldSkip(options)) return Promise.resolve(null);
274
- return http.post("/api/v1/surveys", payload);
275
- }
276
- };
277
- }
278
-
279
- // src/plugins/analytics.ts
280
- function initAnalyticsPlugin(plugeen, http) {
179
+ // src/modules/client/analytics/index.ts
180
+ function initAnalyticsModule(http, logger) {
281
181
  if (typeof window === "undefined") return;
182
+ logger.log("Analytics module started");
282
183
  let pageStartTime = Date.now();
283
- let maxScrollDepth = 0;
284
- let interactionCount = 0;
285
184
  let pageCount = 0;
286
185
  let currentUrl = window.location.href;
287
- const updateScrollDepth = () => {
288
- const scrollY = window.scrollY;
289
- const { scrollHeight, clientHeight } = document.documentElement;
290
- const available = scrollHeight - clientHeight;
291
- if (available <= 0) return;
292
- const depth = Math.min(100, Math.round(scrollY / available * 100));
293
- if (depth > maxScrollDepth) maxScrollDepth = depth;
294
- };
295
- window.addEventListener("scroll", updateScrollDepth, { passive: true });
296
- const countInteraction = () => {
297
- interactionCount++;
298
- };
299
- for (const evt of ["mousedown", "keydown", "touchstart"]) {
300
- window.addEventListener(evt, countInteraction, { passive: true });
301
- }
302
186
  const trackPageView = () => {
303
187
  pageCount++;
304
- const body = {
188
+ void http.post("/v1/analytics", {
305
189
  event: "page_view",
306
190
  url: window.location.href,
307
191
  title: document.title,
@@ -309,33 +193,31 @@ function initAnalyticsPlugin(plugeen, http) {
309
193
  referrer: document.referrer || void 0,
310
194
  screenWidth: window.innerWidth,
311
195
  screenHeight: window.innerHeight
312
- };
313
- void http.post("/api/v1/analytics", body);
196
+ });
314
197
  };
315
- const buildPageExitData = () => ({
316
- url: currentUrl,
317
- time_on_page: Math.round((Date.now() - pageStartTime) / 1e3),
318
- scroll_depth: maxScrollDepth,
319
- interaction_count: interactionCount,
320
- page_count: pageCount
321
- });
322
198
  const trackPageExit = (useBeacon = false) => {
323
- const data = buildPageExitData();
199
+ const data = {
200
+ event: "page_exit",
201
+ url: window.location.href,
202
+ title: document.title,
203
+ sessionId: getOrCreateSessionId(),
204
+ referrer: document.referrer || void 0,
205
+ screenWidth: window.innerWidth,
206
+ screenHeight: window.innerHeight,
207
+ metadata: {
208
+ timeOnPage: Math.round((Date.now() - pageStartTime) / 1e3),
209
+ pageCount
210
+ }
211
+ };
324
212
  if (useBeacon) {
325
- http.send(
326
- "/api/events",
327
- { name: "page_exit", data, source: "api" },
328
- true
329
- );
213
+ http.beacon("/v1/analytics", data);
330
214
  } else {
331
- void plugeen.events.create("page_exit", data);
215
+ void http.post("/v1/analytics", data);
332
216
  }
333
217
  };
334
218
  const onRouteChange = () => {
335
219
  if (window.location.href === currentUrl) return;
336
220
  trackPageExit();
337
- maxScrollDepth = 0;
338
- interactionCount = 0;
339
221
  pageStartTime = Date.now();
340
222
  currentUrl = window.location.href;
341
223
  trackPageView();
@@ -350,18 +232,15 @@ function initAnalyticsPlugin(plugeen, http) {
350
232
  patchHistoryMethod("pushState");
351
233
  patchHistoryMethod("replaceState");
352
234
  window.addEventListener("popstate", onRouteChange);
353
- window.addEventListener("beforeunload", () => {
354
- trackPageExit(true);
355
- });
356
- document.addEventListener("visibilitychange", () => {
357
- if (document.visibilityState === "hidden") {
358
- trackPageExit(true);
359
- }
360
- });
235
+ window.addEventListener("beforeunload", () => trackPageExit(true));
236
+ document.addEventListener(
237
+ "visibilitychange",
238
+ () => document.visibilityState === "hidden" && trackPageExit(true)
239
+ );
361
240
  trackPageView();
362
241
  }
363
242
 
364
- // src/plugins/errors.ts
243
+ // src/modules/client/error/helpers.ts
365
244
  var EXTENSION_PREFIXES = [
366
245
  "chrome-extension://",
367
246
  "moz-extension://",
@@ -373,19 +252,24 @@ function isExtensionSource(str) {
373
252
  const lower = str.toLowerCase();
374
253
  return EXTENSION_PREFIXES.some((prefix) => lower.includes(prefix));
375
254
  }
376
- function initErrorsPlugin(plugeen) {
255
+
256
+ // src/modules/client/error/index.ts
257
+ function initErrorsModule(http, logger) {
377
258
  if (typeof window === "undefined") return;
259
+ logger.log("Errors module started");
378
260
  window.addEventListener("error", (event) => {
379
261
  if (isExtensionSource(event.filename) || isExtensionSource(event.error?.stack))
380
262
  return;
381
263
  if (event.error === null && event.message === "Script error.") return;
382
- void plugeen.events.create("error", {
264
+ void http.post("/v1/logs", {
383
265
  message: event.message || "Unknown Error",
384
- filename: event.filename,
385
- lineno: event.lineno,
386
- colno: event.colno,
387
- stack: event.error?.stack,
388
- error_type: event.error?.name || "Error"
266
+ level: "error",
267
+ url: window.location.href,
268
+ source: "client",
269
+ metadata: {
270
+ stack: event.error?.stack,
271
+ type: event.error?.name
272
+ }
389
273
  });
390
274
  });
391
275
  window.addEventListener(
@@ -404,21 +288,21 @@ function initErrorsPlugin(plugeen) {
404
288
  } else if (reason !== null && typeof reason === "object" && "message" in reason) {
405
289
  message = String(reason.message);
406
290
  }
407
- void plugeen.events.create("error", {
291
+ void http.post("/v1/logs", {
408
292
  message,
409
- stack,
410
- error_type: "UnhandledRejection"
293
+ url: window.location.href,
294
+ source: "client",
295
+ level: "error",
296
+ metadata: {
297
+ stack,
298
+ type: "UnhandledRejection"
299
+ }
411
300
  });
412
301
  }
413
302
  );
414
303
  }
415
304
 
416
- // src/plugins/web-vitals/helpers.ts
417
- function getRating(value, thresholds) {
418
- if (value > thresholds[1]) return "poor";
419
- if (value > thresholds[0]) return "needs-improvement";
420
- return "good";
421
- }
305
+ // src/modules/client/web-vitals/helpers.ts
422
306
  function getActivationStart() {
423
307
  const nav = performance.getEntriesByType(
424
308
  "navigation"
@@ -450,14 +334,10 @@ function observeFCP(cb) {
450
334
  const reported = /* @__PURE__ */ new Set();
451
335
  observe("paint", (entries) => {
452
336
  for (const entry of entries) {
453
- if (entry.name === "first-contentful-paint" && !reported.has("FCP")) {
454
- reported.add("FCP");
337
+ if (entry.name === "first-contentful-paint" && !reported.has("first-contentful-paint")) {
338
+ reported.add("first-contentful-paint");
455
339
  const value = Math.max(entry.startTime - getActivationStart(), 0);
456
- cb({
457
- name: "FCP",
458
- value: Math.round(value),
459
- rating: getRating(value, [1800, 3e3])
460
- });
340
+ cb("first-contentful-paint", Math.round(value));
461
341
  }
462
342
  }
463
343
  });
@@ -469,11 +349,7 @@ function observeLCP(cb) {
469
349
  const last = entries[entries.length - 1];
470
350
  if (last) {
471
351
  const value = Math.max(last.startTime - getActivationStart(), 0);
472
- cb({
473
- name: "LCP",
474
- value: Math.round(value),
475
- rating: getRating(value, [2500, 4e3])
476
- });
352
+ cb("largest-contentful-paint", Math.round(value));
477
353
  }
478
354
  });
479
355
  if (!po) return;
@@ -484,11 +360,7 @@ function observeLCP(cb) {
484
360
  if (records.length > 0) {
485
361
  const last = records[records.length - 1];
486
362
  const value = Math.max(last.startTime - getActivationStart(), 0);
487
- cb({
488
- name: "LCP",
489
- value: Math.round(value),
490
- rating: getRating(value, [2500, 4e3])
491
- });
363
+ cb("largest-contentful-paint", Math.round(value));
492
364
  }
493
365
  po.disconnect();
494
366
  };
@@ -516,11 +388,7 @@ function observeCLS(cb) {
516
388
  if (sessionValue > clsValue) {
517
389
  clsValue = sessionValue;
518
390
  const rounded = Math.round(clsValue * 1e4) / 1e4;
519
- cb({
520
- name: "CLS",
521
- value: rounded,
522
- rating: getRating(clsValue, [0.1, 0.25])
523
- });
391
+ cb("cumulative-layout-shift", rounded);
524
392
  }
525
393
  }
526
394
  });
@@ -529,11 +397,7 @@ function observeTTFB(cb) {
529
397
  const nav = getNavEntry();
530
398
  if (!nav) return;
531
399
  const value = Math.max(nav.responseStart - getActivationStart(), 0);
532
- cb({
533
- name: "TTFB",
534
- value: Math.round(value),
535
- rating: getRating(value, [800, 1800])
536
- });
400
+ cb("time-to-first-byte", Math.round(value));
537
401
  }
538
402
  function observeINP(cb) {
539
403
  const interactions = /* @__PURE__ */ new Map();
@@ -549,11 +413,7 @@ function observeINP(cb) {
549
413
  interactions.set(entry.interactionId, entry.duration);
550
414
  if (entry.duration > worstDuration) {
551
415
  worstDuration = entry.duration;
552
- cb({
553
- name: "INP",
554
- value: Math.round(entry.duration),
555
- rating: getRating(entry.duration, [200, 500])
556
- });
416
+ cb("interaction-to-next-paint", Math.round(entry.duration));
557
417
  }
558
418
  }
559
419
  }
@@ -571,7 +431,7 @@ function observeFPS(cb) {
571
431
  if (performance.now() - start < duration) {
572
432
  requestAnimationFrame(tick);
573
433
  } else {
574
- cb({ name: "FPS", value: Math.round(frames / duration * 1e3) });
434
+ cb("frames-per-second", Math.round(frames / duration * 1e3));
575
435
  }
576
436
  };
577
437
  if (document.readyState === "complete") {
@@ -582,74 +442,103 @@ function observeFPS(cb) {
582
442
  });
583
443
  }
584
444
  }
585
- function initWebVitals(cb) {
586
- if (typeof window === "undefined" || typeof PerformanceObserver === "undefined")
587
- return;
588
- observeFCP(cb);
589
- observeLCP(cb);
590
- observeCLS(cb);
591
- observeTTFB(cb);
592
- observeINP(cb);
593
- observeFPS(cb);
445
+ function initWebVitals() {
446
+ const isBrowser = typeof window !== "undefined";
447
+ const hasPerformanceObserver = typeof PerformanceObserver !== "undefined";
448
+ if (!isBrowser || !hasPerformanceObserver) return [];
449
+ const metrics = /* @__PURE__ */ new Map();
450
+ observeFCP((name, value) => metrics.set(name, value));
451
+ observeLCP((name, value) => metrics.set(name, value));
452
+ observeCLS((name, value) => metrics.set(name, value));
453
+ observeTTFB((name, value) => metrics.set(name, value));
454
+ observeINP((name, value) => metrics.set(name, value));
455
+ observeFPS((name, value) => metrics.set(name, value));
456
+ return Array.from(metrics).map(([name, value]) => ({ name, value }));
594
457
  }
595
458
 
596
- // src/plugins/web-vitals/index.ts
597
- function initWebVitalsPlugin(plugeen) {
598
- initWebVitals((metric) => {
599
- void plugeen.events.create("web_vital", {
600
- name: metric.name,
601
- value: metric.value,
602
- ...metric.rating !== void 0 ? { rating: metric.rating } : {}
603
- });
459
+ // src/modules/client/web-vitals/index.ts
460
+ function initWebVitalsModule(http, logger) {
461
+ logger.log("Web Vitals module started");
462
+ http.post("/v1/web-vitals", {
463
+ url: window.location.href,
464
+ metrics: initWebVitals()
604
465
  });
605
466
  }
606
467
 
607
- // src/plugins/index.ts
608
- function initPlugins(plugeen, http, plugins) {
609
- for (const plugin of plugins) {
610
- if (plugin === "analytics") initAnalyticsPlugin(plugeen, http);
611
- else if (plugin === "web-vitals") initWebVitalsPlugin(plugeen);
612
- else if (plugin === "errors") initErrorsPlugin(plugeen);
613
- }
468
+ // src/modules/identities/index.ts
469
+ function initIdentitiesModule(http, logger) {
470
+ logger.log("Identities module started");
471
+ return {
472
+ async identify(distinctId, data) {
473
+ const res = await http.post("/v1/identities", {
474
+ body: {
475
+ ...data,
476
+ id: distinctId
477
+ }
478
+ });
479
+ setIdentityId(distinctId);
480
+ return res;
481
+ }
482
+ };
483
+ }
484
+
485
+ // src/modules/server/events/index.ts
486
+ function initEventsModule(http, logger) {
487
+ logger.log("Events module started");
488
+ return {
489
+ track: async (name, data = {}) => {
490
+ return http.post("/v1/events", { name, data, source: "sdk" });
491
+ }
492
+ };
493
+ }
494
+
495
+ // src/modules/server/feature-flags/index.ts
496
+ function initFeatureFlagsModule(http, logger) {
497
+ logger.log("Feature Flags module started");
498
+ return {
499
+ get: async (name) => {
500
+ return http.get(`/v1/feature-flags`, { searchParams: { key: name } });
501
+ }
502
+ };
503
+ }
504
+
505
+ // src/modules/server/logs/index.ts
506
+ function initLogsModule(http, logger) {
507
+ logger.log("Logs module started");
508
+ return {
509
+ send: (payload) => http.post("/v1/logs", payload)
510
+ };
614
511
  }
615
512
 
616
513
  // src/index.ts
617
514
  function createPlugeen(apiKey, options) {
618
- if (!apiKey || typeof apiKey !== "string") {
619
- throw new TypeError("[plugeen] apiKey is required");
620
- }
621
- if (!options?.apiUrl || typeof options.apiUrl !== "string") {
622
- throw new TypeError("[plugeen] apiUrl is required");
623
- }
624
515
  const resolved = {
625
- apiUrl: options.apiUrl,
626
- debug: options.debug ?? false,
627
- disabled: options.disabled ?? false,
628
- samplingRate: options.samplingRate ?? 1,
629
- plugins: options.plugins ?? [],
630
- skipPatterns: options.skipPatterns ?? []
516
+ apiUrl: "https://dev.plugeen.app/api",
517
+ debug: false,
518
+ analytics: false,
519
+ webVitals: false,
520
+ errors: false,
521
+ ...options
631
522
  };
523
+ const logger = createLogger(resolved.debug);
524
+ if (!apiKey) {
525
+ throw new TypeError("[plugeen] data-api-key is required");
526
+ }
632
527
  const http = new HttpClient(resolved.apiUrl, apiKey);
633
- const events = createEventsModule(http, resolved);
634
- const identities = createIdentitiesModule(http, resolved);
635
- const featureFlags = createFeatureFlagsModule(http, resolved);
636
- const logs = createLogsModule(http, resolved);
637
- const surveys = createSurveysModule(http, resolved);
638
- const experiments = createExperimentsModule(http, resolved);
639
528
  const plugeen = {
640
- track: (event, properties) => {
641
- void events.create(event, properties ?? {});
642
- },
643
- events,
644
- identities,
645
- featureFlags,
646
- logs,
647
- surveys,
648
- experiments
529
+ track: initEventsModule(http, logger).track,
530
+ identify: initIdentitiesModule(http, logger).identify,
531
+ featureFlags: initFeatureFlagsModule(http, logger),
532
+ logs: initLogsModule(http, logger)
649
533
  };
650
- if (resolved.plugins.length > 0) {
651
- initPlugins(plugeen, http, resolved.plugins);
534
+ if (typeof window !== "undefined") {
535
+ if (resolved.analytics) initAnalyticsModule(http, logger);
536
+ if (resolved.webVitals) initWebVitalsModule(http, logger);
537
+ if (resolved.errors) initErrorsModule(http, logger);
652
538
  }
539
+ logger.log(
540
+ `Running on ${typeof window === "undefined" ? "server" : "client"} side`
541
+ );
653
542
  return plugeen;
654
543
  }
655
544