@proyecta-ai/analytics 0.0.5 → 0.0.7

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/index.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @proyecta-ai/analytics
3
+ * Comprehensive analytics library for Proyecta applications
4
+ */
5
+ import type { ProyectaEvent } from './schema';
6
+ import type { BrowserInfo, OSInfo, ReferrerInfo, UTMParams, PerformanceMetrics, AnalyticsConfig, AnalyticsProvider } from './types';
7
+ import { generateId, getCookie, setCookie, parseUserAgent, getReferrerInfo, getUTMParams, getPerformanceMetrics, observeWebVitals, debounce, throttle, safeStringify, getBrowserInfo } from './utils';
8
+ export type { BrowserInfo, OSInfo, ReferrerInfo, UTMParams, PerformanceMetrics, AnalyticsConfig, AnalyticsProvider, };
9
+ export { generateId, getCookie, setCookie, parseUserAgent, getReferrerInfo, getUTMParams, getPerformanceMetrics, observeWebVitals, debounce, throttle, safeStringify, getBrowserInfo, };
10
+ export declare class Analytics {
11
+ private config;
12
+ private buffer;
13
+ private providers;
14
+ private flushTimer;
15
+ private visitorId;
16
+ private sessionId;
17
+ private userId;
18
+ private webVitalsMetrics;
19
+ constructor(config: AnalyticsConfig);
20
+ private getVisitorId;
21
+ private getSessionId;
22
+ private createEvent;
23
+ private setupClickTracking;
24
+ private sendToEndpoint;
25
+ private startAutoFlush;
26
+ private stopAutoFlush;
27
+ track(eventName: string, properties?: Record<string, string | number>): void;
28
+ private setupWebVitals;
29
+ trackPageview(properties?: Record<string, string | number>): void;
30
+ private trackWebVitals;
31
+ trackPageleave(): void;
32
+ addProvider(provider: AnalyticsProvider): void;
33
+ removeProvider(name: string): void;
34
+ flush(): Promise<void>;
35
+ identify(userId: string): void;
36
+ reset(): void;
37
+ destroy(): void;
38
+ }
39
+ export declare class ConsoleProvider implements AnalyticsProvider {
40
+ name: string;
41
+ send(events: ProyectaEvent[]): Promise<void>;
42
+ }
43
+ export declare function initAnalytics(config: AnalyticsConfig): Analytics;
44
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,cAAc,EACd,eAAe,EACf,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,WAAW,EACX,MAAM,EACN,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,CAAC;AAEF,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,cAAc,EACd,eAAe,EACf,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,cAAc,GACf,CAAC;AAEF,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,UAAU,CAA4C;IAC9D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,gBAAgB,CAA0B;gBAEtC,MAAM,EAAE,eAAe;IA2CnC,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,WAAW;IAmDnB,OAAO,CAAC,kBAAkB;YAsBZ,cAAc;IAuB5B,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,aAAa;IAOrB,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI;IAW5E,OAAO,CAAC,cAAc;IAgCtB,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI;IAmBjE,OAAO,CAAC,cAAc;IAsCtB,cAAc,IAAI,IAAI;IAQtB,WAAW,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAO9C,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAW9B,KAAK,IAAI,IAAI;IAOb,OAAO,IAAI,IAAI;CAMhB;AAED,qBAAa,eAAgB,YAAW,iBAAiB;IACvD,IAAI,SAAa;IAEX,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAKnD;AAID,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAehE"}
package/index.js CHANGED
@@ -14,7 +14,6 @@ import {
14
14
  safeStringify,
15
15
  getBrowserInfo
16
16
  } from "./utils";
17
- const DEFAULT_TINYBIRD_ENDPOINT = "https://api.us-east.tinybird.co/v0/events?name=proyecta_events";
18
17
  class Analytics {
19
18
  static {
20
19
  __name(this, "Analytics");
@@ -30,8 +29,7 @@ class Analytics {
30
29
  constructor(config) {
31
30
  this.config = {
32
31
  appId: config.appId,
33
- token: config.token ?? "",
34
- apiEndpoint: config.apiEndpoint ?? DEFAULT_TINYBIRD_ENDPOINT,
32
+ apiEndpoint: config.apiEndpoint ?? "",
35
33
  debug: config.debug ?? false,
36
34
  enabled: config.enabled ?? !!config.appId,
37
35
  bufferSize: config.bufferSize ?? 10,
@@ -154,21 +152,17 @@ class Analytics {
154
152
  });
155
153
  }
156
154
  async sendToEndpoint(events) {
157
- if (!this.config.apiEndpoint || !this.config.enabled || !this.config.token) return;
158
- const ndjson = events.map((e) => JSON.stringify(e)).join("\n");
155
+ if (!this.config.apiEndpoint || !this.config.enabled || !this.config.appId) return;
159
156
  if (this.config.debug) {
160
157
  console.log("[Proyecta Analytics] Sending", events.length, "events");
161
158
  }
162
- const headers = {
163
- "Content-Type": "application/x-ndjson"
164
- };
165
- if (this.config.token) {
166
- headers["Authorization"] = `Bearer ${this.config.token}`;
167
- }
168
- const response = await fetch(this.config.apiEndpoint, {
159
+ const response = await fetch(`${this.config.apiEndpoint}/v1/analytics/batch`, {
169
160
  method: "POST",
170
- headers,
171
- body: ndjson,
161
+ headers: {
162
+ "Content-Type": "application/json",
163
+ "X-App-Id": this.config.appId
164
+ },
165
+ body: JSON.stringify({ events }),
172
166
  keepalive: true
173
167
  });
174
168
  if (!response.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proyecta-ai/analytics",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Analytics client for Proyecta applications",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -30,4 +30,4 @@
30
30
  "web-vitals": "^5.1.0",
31
31
  "zod": "^4.3.6"
32
32
  }
33
- }
33
+ }
package/schema.d.ts ADDED
@@ -0,0 +1,58 @@
1
+ import * as z from 'zod/mini';
2
+ export declare const EventTypeEnum: z.ZodMiniEnum<{
3
+ pageview: "pageview";
4
+ pageleave: "pageleave";
5
+ web_vitals: "web_vitals";
6
+ click: "click";
7
+ custom: "custom";
8
+ }>;
9
+ export type EventType = z.infer<typeof EventTypeEnum>;
10
+ export declare const ProyectaEventSchema: z.ZodMiniObject<{
11
+ app_id: z.ZodMiniString<string>;
12
+ event_id: z.ZodMiniString<string>;
13
+ event_type: z.ZodMiniEnum<{
14
+ pageview: "pageview";
15
+ pageleave: "pageleave";
16
+ web_vitals: "web_vitals";
17
+ click: "click";
18
+ custom: "custom";
19
+ }>;
20
+ event_name: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
21
+ environment: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
22
+ timestamp: z.ZodMiniNumber<number>;
23
+ visitor_id: z.ZodMiniString<string>;
24
+ session_id: z.ZodMiniString<string>;
25
+ user_id: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
26
+ origin: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
27
+ url: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
28
+ url_path: z.ZodMiniString<string>;
29
+ url_query: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
30
+ url_hash: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
31
+ referrer: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
32
+ referrer_domain: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
33
+ referrer_source: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
34
+ browser: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
35
+ browser_version: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
36
+ os: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
37
+ os_version: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
38
+ country_code: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
39
+ region: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
40
+ city: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
41
+ utm_source: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
42
+ utm_medium: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
43
+ utm_campaign: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
44
+ utm_content: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
45
+ utm_term: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniString<string>>>;
46
+ properties: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>>;
47
+ properties_numeric: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniNumber<number>>>>;
48
+ plt: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
49
+ di: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
50
+ fcp: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
51
+ lcp: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
52
+ cls: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
53
+ fid: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
54
+ ttfb: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
55
+ inp: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
56
+ }, z.core.$strip>;
57
+ export type ProyectaEvent = z.infer<typeof ProyectaEventSchema>;
58
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,eAAO,MAAM,aAAa;;;;;;EAAqE,CAAC;AAChG,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEtD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwC9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
package/types.d.ts ADDED
@@ -0,0 +1,51 @@
1
+ import type { ProyectaEvent } from './schema';
2
+ export interface BrowserInfo {
3
+ name: string;
4
+ version: string;
5
+ }
6
+ export interface OSInfo {
7
+ name: string;
8
+ version: string;
9
+ }
10
+ export interface ReferrerInfo {
11
+ referrer: string;
12
+ referrer_domain: string;
13
+ referrer_source: string;
14
+ }
15
+ export interface UTMParams {
16
+ utm_source: string;
17
+ utm_medium: string;
18
+ utm_campaign: string;
19
+ utm_content: string;
20
+ utm_term: string;
21
+ }
22
+ export interface PerformanceMetrics {
23
+ page_load_time?: number;
24
+ dom_interactive?: number;
25
+ time_to_first_byte?: number;
26
+ first_contentful_paint?: number;
27
+ largest_contentful_paint?: number;
28
+ first_input_delay?: number;
29
+ cumulative_layout_shift?: number;
30
+ interaction_to_next_paint?: number;
31
+ }
32
+ export interface AnalyticsConfig {
33
+ /** Required. The app/prototype ID — used to scope events and authenticate with Proyecta Cloud. */
34
+ appId: string;
35
+ /** Proyecta Cloud base URL (e.g. https://cloud.proyecta.dev). */
36
+ apiEndpoint?: string;
37
+ debug?: boolean;
38
+ enabled?: boolean;
39
+ bufferSize?: number;
40
+ flushInterval?: number;
41
+ trackClicks?: boolean;
42
+ trackPerformance?: boolean;
43
+ cookieDomain?: string;
44
+ cookiePath?: string;
45
+ sessionTimeout?: number;
46
+ }
47
+ export interface AnalyticsProvider {
48
+ name: string;
49
+ send: (events: ProyectaEvent[]) => Promise<void>;
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
package/types.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,kGAAkG;IAClG,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD"}
package/utils.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import type { BrowserInfo, OSInfo, ReferrerInfo, UTMParams, PerformanceMetrics } from './types';
2
+ export declare function generateId(): string;
3
+ export declare function getCookie(name: string): string | null;
4
+ export declare function setCookie(name: string, value: string, days: number, domain?: string, path?: string): void;
5
+ export declare function parseUserAgent(ua?: string): {
6
+ browser: BrowserInfo;
7
+ os: OSInfo;
8
+ deviceType: string;
9
+ deviceVendor?: string;
10
+ deviceModel?: string;
11
+ isBot?: boolean;
12
+ };
13
+ export declare function getReferrerInfo(): ReferrerInfo;
14
+ export declare function getUTMParams(url?: string): UTMParams;
15
+ export declare function getPerformanceMetrics(): PerformanceMetrics;
16
+ export declare function observeWebVitals(callback: (metrics: PerformanceMetrics) => void): void;
17
+ export declare function debounce<T extends (...args: Parameters<T>) => ReturnType<T>>(func: T, wait: number): (...args: Parameters<T>) => void;
18
+ export declare function throttle<T extends (...args: Parameters<T>) => ReturnType<T>>(func: T, limit: number): (...args: Parameters<T>) => void;
19
+ export declare function safeStringify(obj: unknown): string;
20
+ export declare function getBrowserInfo(): Record<string, unknown>;
21
+ //# sourceMappingURL=utils.d.ts.map
package/utils.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAEhG,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWrD;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,MAAM,EACf,IAAI,SAAM,GACT,IAAI,CAQN;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAsB,GAAG;IACxD,OAAO,EAAE,WAAW,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CA2DA;AAED,wBAAgB,eAAe,IAAI,YAAY,CAmD9C;AAED,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CASpD;AAED,wBAAgB,qBAAqB,IAAI,kBAAkB,CAiE1D;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI,CAyFtF;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,EAC1E,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAMlC;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,EAC1E,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CASlC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAWlD;AAED,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwCxD"}
package/index.js.map DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["/**\n * @proyecta-ai/analytics\n * Comprehensive analytics library for Proyecta applications\n */\n\nimport type { ProyectaEvent } from './schema';\nimport type {\n BrowserInfo,\n OSInfo,\n ReferrerInfo,\n UTMParams,\n PerformanceMetrics,\n AnalyticsConfig,\n AnalyticsProvider,\n} from './types';\n\nimport {\n generateId,\n getCookie,\n setCookie,\n parseUserAgent,\n getReferrerInfo,\n getUTMParams,\n getPerformanceMetrics,\n observeWebVitals,\n debounce,\n throttle,\n safeStringify,\n getBrowserInfo,\n} from './utils';\n\nexport type {\n BrowserInfo,\n OSInfo,\n ReferrerInfo,\n UTMParams,\n PerformanceMetrics,\n AnalyticsConfig,\n AnalyticsProvider,\n};\n\nexport {\n generateId,\n getCookie,\n setCookie,\n parseUserAgent,\n getReferrerInfo,\n getUTMParams,\n getPerformanceMetrics,\n observeWebVitals,\n debounce,\n throttle,\n safeStringify,\n getBrowserInfo,\n};\n\n/** Default Tinybird Events API endpoint. Override via config.apiEndpoint. */\nconst DEFAULT_TINYBIRD_ENDPOINT = 'https://api.us-east.tinybird.co/v0/events?name=proyecta_events';\n\nexport class Analytics {\n private config: Required<AnalyticsConfig>;\n private buffer: ProyectaEvent[] = [];\n private providers: AnalyticsProvider[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | undefined;\n private visitorId: string;\n private sessionId: string;\n private userId: string | undefined;\n private webVitalsMetrics: PerformanceMetrics = {};\n\n constructor(config: AnalyticsConfig) {\n this.config = {\n appId: config.appId,\n token: config.token ?? '',\n apiEndpoint: config.apiEndpoint ?? DEFAULT_TINYBIRD_ENDPOINT,\n debug: config.debug ?? false,\n enabled: config.enabled ?? !!config.appId,\n bufferSize: config.bufferSize ?? 10,\n flushInterval: config.flushInterval ?? 5000,\n trackClicks: config.trackClicks ?? false,\n trackPerformance: config.trackPerformance ?? true,\n cookieDomain: config.cookieDomain ?? '',\n cookiePath: config.cookiePath ?? '/',\n sessionTimeout: config.sessionTimeout ?? 30,\n };\n\n this.visitorId = this.getVisitorId();\n this.sessionId = this.getSessionId();\n\n if (this.config.flushInterval > 0) {\n this.startAutoFlush();\n }\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n this.flush();\n }\n });\n\n window.addEventListener('beforeunload', () => {\n this.trackPageleave();\n });\n }\n\n if (this.config.trackClicks && typeof document !== 'undefined') {\n this.setupClickTracking();\n }\n\n if (this.config.trackPerformance) {\n this.setupWebVitals();\n }\n }\n\n private getVisitorId(): string {\n let visitorId = getCookie('_pry_vid');\n if (!visitorId) {\n visitorId = generateId();\n setCookie('_pry_vid', visitorId, 365 * 2, this.config.cookieDomain, this.config.cookiePath);\n }\n return visitorId;\n }\n\n private getSessionId(): string {\n if (typeof sessionStorage === 'undefined') {\n return generateId();\n }\n\n let sessionId = sessionStorage.getItem('_pry_sid');\n const lastActivity = sessionStorage.getItem('_pry_last_activity');\n const now = Date.now();\n\n if (sessionId && lastActivity) {\n const timeSinceLastActivity = now - parseInt(lastActivity, 10);\n if (timeSinceLastActivity > this.config.sessionTimeout * 60 * 1000) {\n sessionId = null;\n }\n }\n\n if (!sessionId) {\n sessionId = generateId();\n sessionStorage.setItem('_pry_sid', sessionId);\n }\n\n sessionStorage.setItem('_pry_last_activity', now.toString());\n return sessionId;\n }\n\n private createEvent(\n eventType: ProyectaEvent['event_type'],\n eventName = '',\n properties?: Record<string, string | number>,\n ): ProyectaEvent {\n const { browser, os } = parseUserAgent();\n const referrerInfo = getReferrerInfo();\n const utmParams = getUTMParams();\n const url = new URL(window.location.href);\n\n const event: ProyectaEvent = {\n app_id: this.config.appId,\n event_id: generateId(),\n event_type: eventType,\n event_name: eventName,\n timestamp: Date.now(),\n visitor_id: this.visitorId,\n session_id: this.sessionId,\n ...(this.userId && { user_id: this.userId }),\n origin: url.origin,\n url: url.href,\n url_path: url.pathname,\n url_query: url.search.substring(1),\n url_hash: url.hash.substring(1),\n referrer: referrerInfo.referrer,\n referrer_domain: referrerInfo.referrer_domain,\n referrer_source: referrerInfo.referrer_source,\n browser: browser.name,\n browser_version: browser.version,\n os: os.name,\n os_version: os.version,\n utm_source: utmParams.utm_source,\n utm_medium: utmParams.utm_medium,\n utm_campaign: utmParams.utm_campaign,\n utm_content: utmParams.utm_content,\n utm_term: utmParams.utm_term,\n properties: {},\n properties_numeric: {},\n };\n\n for (const [key, value] of Object.entries(properties || {})) {\n if (typeof value === 'number') {\n event.properties_numeric![key] = value;\n } else {\n event.properties![key] = value;\n }\n }\n\n return event;\n }\n\n private setupClickTracking(): void {\n document.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n const tagName = target.tagName.toLowerCase();\n\n if (tagName === 'a' || tagName === 'button' || target.getAttribute('data-track-click')) {\n const properties: Record<string, string> = {\n element: tagName,\n text: target.textContent?.substring(0, 100) || '',\n class: target.className || '',\n id: target.id || '',\n };\n\n if (tagName === 'a') {\n properties.href = (target as HTMLAnchorElement).href || '';\n }\n\n this.track('click', properties);\n }\n });\n }\n\n private async sendToEndpoint(events: ProyectaEvent[]): Promise<void> {\n if (!this.config.apiEndpoint || !this.config.enabled || !this.config.token) return;\n\n // Tinybird Events API expects NDJSON (newline-delimited JSON)\n const ndjson = events.map((e) => JSON.stringify(e)).join('\\n');\n\n if (this.config.debug) {\n console.log('[Proyecta Analytics] Sending', events.length, 'events');\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/x-ndjson',\n };\n if (this.config.token) {\n headers['Authorization'] = `Bearer ${this.config.token}`;\n }\n\n // Use fetch with keepalive for reliable delivery on page unload.\n // sendBeacon can't set custom headers (needed for Bearer auth).\n const response = await fetch(this.config.apiEndpoint, {\n method: 'POST',\n headers,\n body: ndjson,\n keepalive: true,\n });\n\n if (!response.ok) {\n throw new Error(`Analytics endpoint returned ${response.status}`);\n }\n }\n\n private startAutoFlush(): void {\n this.stopAutoFlush();\n this.flushTimer = setInterval(() => {\n this.flush();\n }, this.config.flushInterval);\n }\n\n private stopAutoFlush(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = undefined;\n }\n }\n\n track(eventName: string, properties?: Record<string, string | number>): void {\n if (!this.config.enabled) return;\n\n const event = this.createEvent('custom', eventName, properties);\n this.buffer.push(event);\n\n if (this.buffer.length >= this.config.bufferSize) {\n this.flush();\n }\n }\n\n private setupWebVitals(): void {\n let webVitalsEventSent = false;\n let webVitalsTimeout: ReturnType<typeof setTimeout> | undefined;\n\n observeWebVitals((metrics) => {\n this.webVitalsMetrics = { ...this.webVitalsMetrics, ...metrics };\n\n if (webVitalsTimeout) {\n clearTimeout(webVitalsTimeout);\n }\n\n const hasCriticalMetrics =\n (this.webVitalsMetrics.largest_contentful_paint !== undefined ||\n this.webVitalsMetrics.first_contentful_paint !== undefined) &&\n this.webVitalsMetrics.cumulative_layout_shift !== undefined;\n\n if (hasCriticalMetrics && !webVitalsEventSent) {\n webVitalsTimeout = setTimeout(() => {\n this.trackWebVitals();\n webVitalsEventSent = true;\n }, 500);\n }\n });\n\n setTimeout(() => {\n if (!webVitalsEventSent) {\n this.trackWebVitals();\n webVitalsEventSent = true;\n }\n }, 5000);\n }\n\n trackPageview(properties?: Record<string, string | number>): void {\n if (!this.config.enabled) return;\n\n const event = this.createEvent('pageview', '', properties);\n\n if (this.config.trackPerformance) {\n const perfMetrics = getPerformanceMetrics();\n if (perfMetrics.page_load_time !== undefined) event.plt = perfMetrics.page_load_time;\n if (perfMetrics.dom_interactive !== undefined) event.di = perfMetrics.dom_interactive;\n if (perfMetrics.time_to_first_byte !== undefined) event.ttfb = perfMetrics.time_to_first_byte;\n }\n\n this.buffer.push(event);\n\n if (this.buffer.length >= this.config.bufferSize) {\n this.flush();\n }\n }\n\n private trackWebVitals(): void {\n if (!this.config.enabled || !this.config.trackPerformance) return;\n\n const hasVitals =\n this.webVitalsMetrics.first_contentful_paint !== undefined ||\n this.webVitalsMetrics.largest_contentful_paint !== undefined ||\n this.webVitalsMetrics.cumulative_layout_shift !== undefined ||\n this.webVitalsMetrics.first_input_delay !== undefined ||\n this.webVitalsMetrics.interaction_to_next_paint !== undefined;\n\n if (!hasVitals) return;\n\n const event = this.createEvent('web_vitals', '');\n\n if (this.webVitalsMetrics.first_contentful_paint !== undefined)\n event.fcp = this.webVitalsMetrics.first_contentful_paint;\n if (this.webVitalsMetrics.largest_contentful_paint !== undefined)\n event.lcp = this.webVitalsMetrics.largest_contentful_paint;\n if (this.webVitalsMetrics.cumulative_layout_shift !== undefined)\n event.cls = this.webVitalsMetrics.cumulative_layout_shift;\n if (this.webVitalsMetrics.first_input_delay !== undefined)\n event.fid = this.webVitalsMetrics.first_input_delay;\n if (this.webVitalsMetrics.interaction_to_next_paint !== undefined)\n event.inp = this.webVitalsMetrics.interaction_to_next_paint;\n if (this.webVitalsMetrics.time_to_first_byte !== undefined)\n event.ttfb = this.webVitalsMetrics.time_to_first_byte;\n if (this.webVitalsMetrics.page_load_time !== undefined)\n event.plt = this.webVitalsMetrics.page_load_time;\n if (this.webVitalsMetrics.dom_interactive !== undefined)\n event.di = this.webVitalsMetrics.dom_interactive;\n\n this.buffer.push(event);\n\n if (this.buffer.length >= this.config.bufferSize) {\n this.flush();\n }\n }\n\n trackPageleave(): void {\n if (!this.config.enabled) return;\n\n const event = this.createEvent('pageleave', '');\n this.buffer.push(event);\n this.flush();\n }\n\n addProvider(provider: AnalyticsProvider): void {\n this.providers.push(provider);\n if (this.config.debug) {\n console.log(`[Proyecta Analytics] Provider '${provider.name}' added`);\n }\n }\n\n removeProvider(name: string): void {\n this.providers = this.providers.filter((p) => p.name !== name);\n }\n\n async flush(): Promise<void> {\n if (this.buffer.length === 0) return;\n\n const events = [...this.buffer];\n this.buffer = [];\n\n try {\n await Promise.all([\n ...this.providers.map((provider) =>\n provider.send(events).catch((err) => {\n if (this.config.debug) {\n console.error(`[Proyecta Analytics] Provider '${provider.name}' error:`, err);\n }\n }),\n ),\n this.sendToEndpoint(events).catch((err) => {\n if (this.config.debug) {\n console.error('[Proyecta Analytics] Endpoint error:', err);\n }\n }),\n ]);\n\n if (this.config.debug) {\n console.log(`[Proyecta Analytics] Flushed ${events.length} events`);\n }\n } catch (error) {\n if (this.config.debug) {\n console.error('[Proyecta Analytics] Flush error:', error);\n }\n this.buffer.unshift(...events);\n }\n }\n\n identify(userId: string): void {\n this.userId = userId;\n if (this.config.enabled) {\n const event = this.createEvent('custom', 'identify', { user_id: userId });\n this.buffer.push(event);\n if (this.buffer.length >= this.config.bufferSize) {\n this.flush();\n }\n }\n }\n\n reset(): void {\n this.buffer = [];\n this.sessionId = this.getSessionId();\n this.userId = undefined;\n this.webVitalsMetrics = {};\n }\n\n destroy(): void {\n this.stopAutoFlush();\n this.flush();\n this.providers = [];\n this.buffer = [];\n }\n}\n\nexport class ConsoleProvider implements AnalyticsProvider {\n name = 'console';\n\n async send(events: ProyectaEvent[]): Promise<void> {\n events.forEach((event) => {\n console.log('[ConsoleProvider]', event);\n });\n }\n}\n\nlet defaultInstance: Analytics | null = null;\n\nexport function initAnalytics(config: AnalyticsConfig): Analytics {\n if (!defaultInstance) {\n defaultInstance = new Analytics(config);\n\n if (typeof window !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n defaultInstance?.trackPageview();\n });\n } else {\n defaultInstance?.trackPageview();\n }\n }\n }\n return defaultInstance;\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
package/schema.js.map DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/schema.ts"],
4
- "sourcesContent": ["import * as z from 'zod/mini';\n\nexport const EventTypeEnum = z.enum(['pageview', 'pageleave', 'web_vitals', 'click', 'custom']);\nexport type EventType = z.infer<typeof EventTypeEnum>;\n\nexport const ProyectaEventSchema = z.object({\n app_id: z.string(),\n event_id: z.string(),\n event_type: EventTypeEnum,\n event_name: z.nullish(z.string()),\n environment: z.nullish(z.string()),\n timestamp: z.number(),\n visitor_id: z.string(),\n session_id: z.string(),\n user_id: z.nullish(z.string()),\n origin: z.nullish(z.string()),\n url: z.nullish(z.string()),\n url_path: z.string(),\n url_query: z.nullish(z.string()),\n url_hash: z.nullish(z.string()),\n referrer: z.nullish(z.string()),\n referrer_domain: z.nullish(z.string()),\n referrer_source: z.nullish(z.string()),\n browser: z.nullish(z.string()),\n browser_version: z.nullish(z.string()),\n os: z.nullish(z.string()),\n os_version: z.nullish(z.string()),\n country_code: z.nullish(z.string().check(z.minLength(2))),\n region: z.nullish(z.string()),\n city: z.nullish(z.string()),\n utm_source: z.nullish(z.string()),\n utm_medium: z.nullish(z.string()),\n utm_campaign: z.nullish(z.string()),\n utm_content: z.nullish(z.string()),\n utm_term: z.nullish(z.string()),\n properties: z.nullish(z.record(z.string(), z.string())),\n properties_numeric: z.nullish(z.record(z.string(), z.number())),\n plt: z.nullish(z.number()),\n di: z.nullish(z.number()),\n fcp: z.nullish(z.number()),\n lcp: z.nullish(z.number()),\n cls: z.nullish(z.number()),\n fid: z.nullish(z.number()),\n ttfb: z.nullish(z.number()),\n inp: z.nullish(z.number()),\n});\nexport type ProyectaEvent = z.infer<typeof ProyectaEventSchema>;\n"],
5
- "mappings": "AAAA,YAAY,OAAO;AAEZ,MAAM,gBAAgB,EAAE,KAAK,CAAC,YAAY,aAAa,cAAc,SAAS,QAAQ,CAAC;AAGvF,MAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,QAAQ,EAAE,OAAO;AAAA,EACjB,UAAU,EAAE,OAAO;AAAA,EACnB,YAAY;AAAA,EACZ,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAChC,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACjC,WAAW,EAAE,OAAO;AAAA,EACpB,YAAY,EAAE,OAAO;AAAA,EACrB,YAAY,EAAE,OAAO;AAAA,EACrB,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC7B,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC5B,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACzB,UAAU,EAAE,OAAO;AAAA,EACnB,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC/B,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC9B,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC9B,iBAAiB,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACrC,iBAAiB,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACrC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC7B,iBAAiB,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACrC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACxB,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAChC,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAAA,EACxD,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC5B,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC1B,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAChC,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAChC,cAAc,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAClC,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACjC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC9B,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACtD,oBAAoB,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EAC9D,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACzB,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACxB,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACzB,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACzB,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACzB,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACzB,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EAC1B,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC;AAC3B,CAAC;",
6
- "names": []
7
- }
package/types.js.map DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
package/utils.js.map DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/utils.ts"],
4
- "sourcesContent": ["import { ulid } from 'ulid';\nimport { onCLS, onFCP, onLCP, onTTFB, onINP, type Metric } from 'web-vitals';\nimport Bowser from 'bowser';\nimport type { BrowserInfo, OSInfo, ReferrerInfo, UTMParams, PerformanceMetrics } from './types';\n\nexport function generateId(): string {\n return ulid();\n}\n\nexport function getCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n const value = `; ${document.cookie}`;\n const parts = value.split(`; ${name}=`);\n if (parts.length === 2) {\n const part = parts.pop();\n if (part) {\n return part.split(';').shift() || null;\n }\n }\n return null;\n}\n\nexport function setCookie(\n name: string,\n value: string,\n days: number,\n domain?: string,\n path = '/',\n): void {\n if (typeof document === 'undefined') return;\n const expires = new Date(Date.now() + days * 864e5).toUTCString();\n let cookie = `${name}=${value}; expires=${expires}; path=${path}; SameSite=Lax`;\n if (domain) {\n cookie += `; domain=${domain}`;\n }\n document.cookie = cookie;\n}\n\nexport function parseUserAgent(ua = navigator.userAgent): {\n browser: BrowserInfo;\n os: OSInfo;\n deviceType: string;\n deviceVendor?: string;\n deviceModel?: string;\n isBot?: boolean;\n} {\n const parser = Bowser.getParser(ua);\n const browserInfo = parser.getBrowser();\n const osInfo = parser.getOS();\n const platformInfo = parser.getPlatform();\n\n const browser: BrowserInfo = {\n name: browserInfo.name?.toLowerCase() || '',\n version: browserInfo.version?.split('.')[0] || '',\n };\n\n const os: OSInfo = {\n name: osInfo.name?.toLowerCase().replace(/ /g, '') || '',\n version: osInfo.version || '',\n };\n\n if (os.name === 'macos') {\n os.name = 'macos';\n } else if (os.name === 'windows') {\n os.name = 'windows';\n } else if (os.name === 'ios') {\n os.name = 'ios';\n } else if (os.name === 'android') {\n os.name = 'android';\n } else if (os.name.includes('linux')) {\n os.name = 'linux';\n }\n\n const platformType = platformInfo.type;\n let deviceType = 'desktop';\n\n if (platformType === 'mobile') {\n deviceType = 'mobile';\n } else if (platformType === 'tablet') {\n deviceType = 'tablet';\n } else if (platformType === 'tv') {\n deviceType = 'tv';\n } else if (platformType === 'wearable') {\n deviceType = 'wearable';\n } else if (platformType === 'embedded') {\n deviceType = 'embedded';\n }\n\n const deviceVendor = platformInfo.vendor;\n const deviceModel = platformInfo.model;\n\n const isBot =\n parser.satisfies({\n crawler: ['bot', 'crawler', 'spider', 'crawling'],\n }) || parser.getBrowserName() === 'bot';\n\n return {\n browser,\n os,\n deviceType,\n ...(deviceVendor && { deviceVendor }),\n ...(deviceModel && { deviceModel }),\n ...(isBot && { isBot }),\n };\n}\n\nexport function getReferrerInfo(): ReferrerInfo {\n const referrer = document.referrer;\n if (!referrer) {\n return {\n referrer: '',\n referrer_domain: '',\n referrer_source: 'direct',\n };\n }\n\n try {\n const url = new URL(referrer);\n const domain = url.hostname;\n let source = 'referral';\n\n const sourceMap: Record<string, string[]> = {\n google: ['google.'],\n facebook: ['facebook.', 'fb.'],\n twitter: ['twitter.', 't.co', 'x.com'],\n linkedin: ['linkedin.'],\n instagram: ['instagram.'],\n youtube: ['youtube.'],\n reddit: ['reddit.'],\n pinterest: ['pinterest.'],\n bing: ['bing.'],\n yahoo: ['yahoo.'],\n duckduckgo: ['duckduckgo.'],\n baidu: ['baidu.'],\n yandex: ['yandex.'],\n tiktok: ['tiktok.'],\n };\n\n for (const [key, domains] of Object.entries(sourceMap)) {\n if (domains.some((d) => domain.includes(d))) {\n source = key;\n break;\n }\n }\n\n return {\n referrer,\n referrer_domain: domain,\n referrer_source: source,\n };\n } catch {\n return {\n referrer,\n referrer_domain: '',\n referrer_source: 'unknown',\n };\n }\n}\n\nexport function getUTMParams(url?: string): UTMParams {\n const params = new URLSearchParams(url || window.location.search);\n return {\n utm_source: params.get('utm_source') || '',\n utm_medium: params.get('utm_medium') || '',\n utm_campaign: params.get('utm_campaign') || '',\n utm_content: params.get('utm_content') || '',\n utm_term: params.get('utm_term') || '',\n };\n}\n\nexport function getPerformanceMetrics(): PerformanceMetrics {\n const metrics: PerformanceMetrics = {};\n\n if (typeof window === 'undefined' || !('performance' in window)) {\n return metrics;\n }\n\n if (window.performance && typeof window.performance.getEntriesByType === 'function') {\n try {\n const navigationEntries = performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (navigationEntries.length > 0) {\n const navTiming = navigationEntries[0];\n if (navTiming) {\n const pageLoadTime = navTiming.loadEventEnd - navTiming.fetchStart;\n const domInteractive = navTiming.domInteractive - navTiming.fetchStart;\n const ttfb = navTiming.responseStart - navTiming.requestStart;\n\n if (pageLoadTime > 0 && isFinite(pageLoadTime)) {\n metrics.page_load_time = Math.round(pageLoadTime);\n }\n if (domInteractive > 0 && isFinite(domInteractive)) {\n metrics.dom_interactive = Math.round(domInteractive);\n }\n if (ttfb > 0 && isFinite(ttfb)) {\n metrics.time_to_first_byte = Math.round(ttfb);\n }\n }\n }\n } catch {\n // Navigation Timing API Level 2 not supported\n }\n }\n\n if (!metrics.page_load_time && performance.timing) {\n const timing = performance.timing;\n const pageLoadTime = timing.loadEventEnd - timing.navigationStart;\n const domInteractive = timing.domInteractive - timing.navigationStart;\n const ttfb = timing.responseStart - timing.navigationStart;\n\n if (pageLoadTime > 0 && isFinite(pageLoadTime)) {\n metrics.page_load_time = Math.round(pageLoadTime);\n }\n if (domInteractive > 0 && isFinite(domInteractive)) {\n metrics.dom_interactive = Math.round(domInteractive);\n }\n if (ttfb > 0 && isFinite(ttfb)) {\n metrics.time_to_first_byte = Math.round(ttfb);\n }\n }\n\n if (window.performance && typeof window.performance.getEntriesByType === 'function') {\n try {\n const paintEntries = performance.getEntriesByType('paint') as PerformanceEntry[];\n const fcpEntry = paintEntries.find((entry) => entry.name === 'first-contentful-paint');\n if (fcpEntry) {\n metrics.first_contentful_paint = Math.round(fcpEntry.startTime);\n }\n } catch {\n // Paint metrics not supported\n }\n }\n\n return metrics;\n}\n\nexport function observeWebVitals(callback: (metrics: PerformanceMetrics) => void): void {\n if (typeof window === 'undefined') {\n return;\n }\n\n const metrics: PerformanceMetrics = {};\n\n const updateMetrics = (name: keyof PerformanceMetrics, value: number) => {\n metrics[name] = Math.round(value);\n callback({ ...metrics });\n };\n\n onCLS(\n (metric: Metric) => {\n metrics.cumulative_layout_shift = Math.round(metric.value * 1000) / 1000;\n callback({ ...metrics });\n },\n { reportAllChanges: false },\n );\n\n onFCP((metric: Metric) => {\n updateMetrics('first_contentful_paint', metric.value);\n });\n\n onLCP(\n (metric: Metric) => {\n updateMetrics('largest_contentful_paint', metric.value);\n },\n { reportAllChanges: false },\n );\n\n onTTFB((metric: Metric) => {\n updateMetrics('time_to_first_byte', metric.value);\n });\n\n onINP(\n (metric: Metric) => {\n updateMetrics('interaction_to_next_paint', metric.value);\n if (metrics.first_input_delay === undefined) {\n updateMetrics('first_input_delay', metric.value);\n }\n },\n { reportAllChanges: false },\n );\n\n if (window.performance && typeof window.performance.getEntriesByType === 'function') {\n const checkPageLoad = () => {\n try {\n const navigationEntries = performance.getEntriesByType(\n 'navigation',\n ) as PerformanceNavigationTiming[];\n if (navigationEntries.length > 0) {\n const navTiming = navigationEntries[0];\n if (navTiming && navTiming.loadEventEnd > 0) {\n const pageLoadTime = navTiming.loadEventEnd - navTiming.fetchStart;\n if (pageLoadTime > 0 && isFinite(pageLoadTime)) {\n updateMetrics('page_load_time', pageLoadTime);\n }\n const domInteractive = navTiming.domInteractive - navTiming.fetchStart;\n if (domInteractive > 0 && isFinite(domInteractive)) {\n updateMetrics('dom_interactive', domInteractive);\n }\n } else {\n setTimeout(checkPageLoad, 100);\n }\n }\n } catch {\n if (performance.timing && performance.timing.loadEventEnd > 0) {\n const timing = performance.timing;\n const pageLoadTime = timing.loadEventEnd - timing.navigationStart;\n if (pageLoadTime > 0 && isFinite(pageLoadTime)) {\n updateMetrics('page_load_time', pageLoadTime);\n }\n const domInteractive = timing.domInteractive - timing.navigationStart;\n if (domInteractive > 0 && isFinite(domInteractive)) {\n updateMetrics('dom_interactive', domInteractive);\n }\n }\n }\n };\n\n if (document.readyState === 'complete') {\n setTimeout(checkPageLoad, 0);\n } else {\n window.addEventListener('load', () => {\n setTimeout(checkPageLoad, 0);\n });\n }\n }\n}\n\nexport function debounce<T extends (...args: Parameters<T>) => ReturnType<T>>(\n func: T,\n wait: number,\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout>;\n return (...args: Parameters<T>) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => func(...args), wait);\n };\n}\n\nexport function throttle<T extends (...args: Parameters<T>) => ReturnType<T>>(\n func: T,\n limit: number,\n): (...args: Parameters<T>) => void {\n let inThrottle: boolean;\n return (...args: Parameters<T>) => {\n if (!inThrottle) {\n func(...args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), limit);\n }\n };\n}\n\nexport function safeStringify(obj: unknown): string {\n const seen = new WeakSet();\n return JSON.stringify(obj, (_key, value) => {\n if (typeof value === 'object' && value !== null) {\n if (seen.has(value)) {\n return '[Circular]';\n }\n seen.add(value);\n }\n return value;\n });\n}\n\nexport function getBrowserInfo(): Record<string, unknown> {\n if (typeof window === 'undefined') return {};\n\n const { browser, os, deviceType, deviceVendor, deviceModel, isBot } = parseUserAgent();\n const parser = Bowser.getParser(navigator.userAgent);\n\n const engineInfo = parser.getEngine();\n const browserFeatures = {\n isMobile: parser.getPlatformType() === 'mobile',\n isTablet: parser.getPlatformType() === 'tablet',\n isDesktop: parser.getPlatformType() === 'desktop',\n isTouchEnabled: 'ontouchstart' in window || navigator.maxTouchPoints > 0,\n };\n\n return {\n userAgent: navigator.userAgent,\n language: navigator.language,\n languages: navigator.languages,\n platform: navigator.platform,\n cookieEnabled: navigator.cookieEnabled,\n onLine: navigator.onLine,\n screenResolution: `${screen.width}x${screen.height}`,\n screenColorDepth: screen.colorDepth,\n pixelRatio: window.devicePixelRatio || 1,\n viewport: `${window.innerWidth}x${window.innerHeight}`,\n referrer: document.referrer,\n url: window.location.href,\n title: document.title,\n browser: browser.name,\n browserVersion: browser.version,\n browserEngine: engineInfo.name || '',\n browserEngineVersion: engineInfo.version || '',\n os: os.name,\n osVersion: os.version,\n deviceType,\n deviceVendor,\n deviceModel,\n isBot,\n ...browserFeatures,\n };\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }