@arthurreira/analytics 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -176,11 +176,8 @@ var AfAnalytics = (() => {
176
176
  function trackScroll(apiUrl, apiKey, sessionId, depth) {
177
177
  send(apiUrl, apiKey, __spreadProps(__spreadValues({}, baseFields(sessionId, "scroll")), { scroll_depth: depth }));
178
178
  }
179
- function trackError(apiUrl, apiKey, sessionId, error) {
180
- send(apiUrl, apiKey, __spreadProps(__spreadValues({}, baseFields(sessionId, "error")), {
181
- error_message: error.message,
182
- stack_trace: error.stack || null
183
- }));
179
+ function trackException(apiUrl, apiKey, sessionId, fields) {
180
+ send(apiUrl, apiKey, __spreadValues(__spreadValues({}, baseFields(sessionId, "js_exception")), fields));
184
181
  }
185
182
  function init() {
186
183
  const config = readConfig();
@@ -223,7 +220,31 @@ var AfAnalytics = (() => {
223
220
  { passive: true }
224
221
  );
225
222
  window.addEventListener("error", (e) => {
226
- enqueue((id) => trackError(apiUrl, apiKey, id, new Error(e.message)));
223
+ enqueue((id) => {
224
+ var _a, _b, _c, _d, _e, _f, _g;
225
+ return trackException(apiUrl, apiKey, id, {
226
+ exception_type: (_b = (_a = e.error) == null ? void 0 : _a.name) != null ? _b : "Error",
227
+ exception_message: e.message,
228
+ exception_filename: (_c = e.filename) != null ? _c : null,
229
+ exception_lineno: (_d = e.lineno) != null ? _d : null,
230
+ exception_colno: (_e = e.colno) != null ? _e : null,
231
+ stack_trace: (_g = (_f = e.error) == null ? void 0 : _f.stack) != null ? _g : null
232
+ });
233
+ });
234
+ });
235
+ window.addEventListener("unhandledrejection", (e) => {
236
+ const reason = e.reason;
237
+ enqueue((id) => {
238
+ var _a, _b, _c;
239
+ return trackException(apiUrl, apiKey, id, {
240
+ exception_type: (_a = reason == null ? void 0 : reason.name) != null ? _a : "UnhandledRejection",
241
+ exception_message: (_b = reason == null ? void 0 : reason.message) != null ? _b : String(reason),
242
+ exception_filename: null,
243
+ exception_lineno: null,
244
+ exception_colno: null,
245
+ stack_trace: (_c = reason == null ? void 0 : reason.stack) != null ? _c : null
246
+ });
247
+ });
227
248
  });
228
249
  const endSession = () => {
229
250
  if (!sessionId || sessionEnded) return;
package/dist/client.d.ts CHANGED
@@ -5,6 +5,15 @@ interface AnalyticsProps {
5
5
  }
6
6
  declare function Analytics({ apiKey, apiUrl, wsUrl }: AnalyticsProps): null;
7
7
 
8
+ interface ExceptionFields {
9
+ exception_type: string;
10
+ exception_message: string;
11
+ exception_filename: string | null;
12
+ exception_lineno: number | null;
13
+ exception_colno: number | null;
14
+ stack_trace: string | null;
15
+ }
16
+
8
17
  declare function useAnalytics(apiUrl: string, apiKey: string, options?: {
9
18
  wsUrl?: string;
10
19
  }): {
@@ -12,6 +21,7 @@ declare function useAnalytics(apiUrl: string, apiKey: string, options?: {
12
21
  trackClick: (e: MouseEvent, element: HTMLElement) => void;
13
22
  trackScroll: (depth: number) => void;
14
23
  trackCopy: () => void;
24
+ trackException: (fields: ExceptionFields) => void;
15
25
  trackError: (error: Error) => void;
16
26
  trackCTA: (ctaId: string, ctaVariant?: string) => void;
17
27
  trackSearch: (query: string) => void;
package/dist/client.js CHANGED
@@ -109,11 +109,20 @@ async function trackSearch(apiUrl, apiKey, sessionId, path, query) {
109
109
  search_query: query
110
110
  });
111
111
  }
112
- async function trackError(apiUrl, apiKey, sessionId, path, error) {
112
+ async function trackException(apiUrl, apiKey, sessionId, path, fields) {
113
113
  await sendEvent(apiUrl, apiKey, {
114
- ...BASE_FIELDS(sessionId, "error", path),
115
- error_message: error.message,
116
- stack_trace: error.stack || null
114
+ ...BASE_FIELDS(sessionId, "js_exception", path),
115
+ ...fields
116
+ });
117
+ }
118
+ async function trackError(apiUrl, apiKey, sessionId, path, error) {
119
+ await trackException(apiUrl, apiKey, sessionId, path, {
120
+ exception_type: error.name ?? "Error",
121
+ exception_message: error.message,
122
+ exception_filename: null,
123
+ exception_lineno: null,
124
+ exception_colno: null,
125
+ stack_trace: error.stack ?? null
117
126
  });
118
127
  }
119
128
  async function trackCTA(apiUrl, apiKey, sessionId, path, ctaId, ctaVariant) {
@@ -180,6 +189,7 @@ function connectPresence(apiKey, sessionId, wsUrl = DEFAULT_WS_URL) {
180
189
 
181
190
  // src/hooks/useAnalytics.ts
182
191
  var SESSION_EXPIRY_MINUTES = 30;
192
+ var _sessionFlight = null;
183
193
  async function getOrCreateSession(apiUrl, apiKey, visitorId) {
184
194
  const storedSessionId = localStorage.getItem("af_session_id");
185
195
  const lastActivity = localStorage.getItem("af_session_last_activity");
@@ -191,10 +201,17 @@ async function getOrCreateSession(apiUrl, apiKey, visitorId) {
191
201
  return storedSessionId;
192
202
  }
193
203
  }
194
- const newSessionId = await createSession(apiUrl, apiKey, visitorId);
195
- localStorage.setItem("af_session_id", newSessionId);
196
- localStorage.setItem("af_session_last_activity", String(now));
197
- return newSessionId;
204
+ if (_sessionFlight) return _sessionFlight;
205
+ _sessionFlight = createSession(apiUrl, apiKey, visitorId).then((id) => {
206
+ localStorage.setItem("af_session_id", id);
207
+ localStorage.setItem("af_session_last_activity", String(Date.now()));
208
+ _sessionFlight = null;
209
+ return id;
210
+ }).catch((err) => {
211
+ _sessionFlight = null;
212
+ throw err;
213
+ });
214
+ return _sessionFlight;
198
215
  }
199
216
  function useAnalytics(apiUrl, apiKey, options) {
200
217
  const sessionId = useRef(null);
@@ -261,6 +278,9 @@ function useAnalytics(apiUrl, apiKey, options) {
261
278
  trackCopy: () => {
262
279
  enqueueOrRun(() => trackCopy(apiUrl, apiKey, sessionId.current, pathname.current));
263
280
  },
281
+ trackException: (fields) => {
282
+ enqueueOrRun(() => trackException(apiUrl, apiKey, sessionId.current, pathname.current, fields));
283
+ },
264
284
  trackError: (error) => {
265
285
  enqueueOrRun(() => trackError(apiUrl, apiKey, sessionId.current, pathname.current, error));
266
286
  },
@@ -275,7 +295,7 @@ function useAnalytics(apiUrl, apiKey, options) {
275
295
 
276
296
  // src/components/Analytics.tsx
277
297
  function Analytics({ apiKey, apiUrl, wsUrl }) {
278
- const { trackPageview: trackPageview2, trackClick: trackClick2, trackScroll: trackScroll2, trackCopy: trackCopy2, trackError: trackError2 } = useAnalytics(apiUrl, apiKey, { wsUrl });
298
+ const { trackPageview: trackPageview2, trackClick: trackClick2, trackScroll: trackScroll2, trackCopy: trackCopy2, trackException: trackException2 } = useAnalytics(apiUrl, apiKey, { wsUrl });
279
299
  const lastTracked = useRef2(null);
280
300
  const lastScrollDepth = useRef2(0);
281
301
  const pathname = typeof window !== "undefined" ? window.location.pathname : "";
@@ -316,10 +336,33 @@ function Analytics({ apiKey, apiUrl, wsUrl }) {
316
336
  }, [trackCopy2]);
317
337
  useEffect2(() => {
318
338
  if (typeof window === "undefined") return;
319
- const handler = (e) => trackError2(new Error(e.message));
339
+ const handler = (e) => trackException2({
340
+ exception_type: e.error?.name ?? "Error",
341
+ exception_message: e.message,
342
+ exception_filename: e.filename ?? null,
343
+ exception_lineno: e.lineno ?? null,
344
+ exception_colno: e.colno ?? null,
345
+ stack_trace: e.error?.stack ?? null
346
+ });
320
347
  window.addEventListener("error", handler);
321
348
  return () => window.removeEventListener("error", handler);
322
- }, [trackError2]);
349
+ }, [trackException2]);
350
+ useEffect2(() => {
351
+ if (typeof window === "undefined") return;
352
+ const handler = (e) => {
353
+ const reason = e.reason;
354
+ trackException2({
355
+ exception_type: reason?.name ?? "UnhandledRejection",
356
+ exception_message: reason?.message ?? String(reason),
357
+ exception_filename: null,
358
+ exception_lineno: null,
359
+ exception_colno: null,
360
+ stack_trace: reason?.stack ?? null
361
+ });
362
+ };
363
+ window.addEventListener("unhandledrejection", handler);
364
+ return () => window.removeEventListener("unhandledrejection", handler);
365
+ }, [trackException2]);
323
366
  return null;
324
367
  }
325
368
  export {
package/dist/index.d.ts CHANGED
@@ -4,6 +4,15 @@ declare function trackClick(apiUrl: string, apiKey: string, sessionId: string, p
4
4
  declare function trackScroll(apiUrl: string, apiKey: string, sessionId: string, path: string, depth: number): Promise<void>;
5
5
  declare function trackCopy(apiUrl: string, apiKey: string, sessionId: string, path: string): Promise<void>;
6
6
  declare function trackSearch(apiUrl: string, apiKey: string, sessionId: string, path: string, query: string): Promise<void>;
7
+ interface ExceptionFields {
8
+ exception_type: string;
9
+ exception_message: string;
10
+ exception_filename: string | null;
11
+ exception_lineno: number | null;
12
+ exception_colno: number | null;
13
+ stack_trace: string | null;
14
+ }
15
+ declare function trackException(apiUrl: string, apiKey: string, sessionId: string, path: string, fields: ExceptionFields): Promise<void>;
7
16
  declare function trackError(apiUrl: string, apiKey: string, sessionId: string, path: string, error: Error): Promise<void>;
8
17
  declare function trackCTA(apiUrl: string, apiKey: string, sessionId: string, path: string, ctaId: string, ctaVariant?: string): Promise<void>;
9
18
 
@@ -13,4 +22,4 @@ interface PresenceConnection {
13
22
  }
14
23
  declare function connectPresence(apiKey: string, sessionId: string, wsUrl?: string): PresenceConnection;
15
24
 
16
- export { DEFAULT_WS_URL, type PresenceConnection, connectPresence, createSession, trackCTA, trackClick, trackCopy, trackError, trackPageview, trackScroll, trackSearch };
25
+ export { DEFAULT_WS_URL, type ExceptionFields, type PresenceConnection, connectPresence, createSession, trackCTA, trackClick, trackCopy, trackError, trackException, trackPageview, trackScroll, trackSearch };
package/dist/index.js CHANGED
@@ -100,11 +100,20 @@ async function trackSearch(apiUrl, apiKey, sessionId, path, query) {
100
100
  search_query: query
101
101
  });
102
102
  }
103
- async function trackError(apiUrl, apiKey, sessionId, path, error) {
103
+ async function trackException(apiUrl, apiKey, sessionId, path, fields) {
104
104
  await sendEvent(apiUrl, apiKey, {
105
- ...BASE_FIELDS(sessionId, "error", path),
106
- error_message: error.message,
107
- stack_trace: error.stack || null
105
+ ...BASE_FIELDS(sessionId, "js_exception", path),
106
+ ...fields
107
+ });
108
+ }
109
+ async function trackError(apiUrl, apiKey, sessionId, path, error) {
110
+ await trackException(apiUrl, apiKey, sessionId, path, {
111
+ exception_type: error.name ?? "Error",
112
+ exception_message: error.message,
113
+ exception_filename: null,
114
+ exception_lineno: null,
115
+ exception_colno: null,
116
+ stack_trace: error.stack ?? null
108
117
  });
109
118
  }
110
119
  async function trackCTA(apiUrl, apiKey, sessionId, path, ctaId, ctaVariant) {
@@ -176,6 +185,7 @@ export {
176
185
  trackClick,
177
186
  trackCopy,
178
187
  trackError,
188
+ trackException,
179
189
  trackPageview,
180
190
  trackScroll,
181
191
  trackSearch
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  { "name": "@arthurreira/analytics",
2
- "version": "0.12.0",
2
+ "version": "0.14.0",
3
3
  "type": "module",
4
4
  "scripts": {
5
5
  "build": "tsup",