@outlit/browser 0.2.0 → 0.2.1

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.
@@ -32,7 +32,7 @@ module.exports = __toCommonJS(react_exports);
32
32
  var import_react = require("react");
33
33
 
34
34
  // src/tracker.ts
35
- var import_core2 = require("@outlit/core");
35
+ var import_core3 = require("@outlit/core");
36
36
 
37
37
  // src/autocapture.ts
38
38
  var import_core = require("@outlit/core");
@@ -52,19 +52,22 @@ function capturePageview() {
52
52
  lastUrl = url;
53
53
  pageviewCallback(url, referrer, title);
54
54
  }
55
+ function capturePageviewDelayed() {
56
+ setTimeout(capturePageview, 10);
57
+ }
55
58
  function setupSpaListeners() {
56
59
  window.addEventListener("popstate", () => {
57
- capturePageview();
60
+ capturePageviewDelayed();
58
61
  });
59
62
  const originalPushState = history.pushState;
60
63
  const originalReplaceState = history.replaceState;
61
64
  history.pushState = function(...args) {
62
65
  originalPushState.apply(this, args);
63
- capturePageview();
66
+ capturePageviewDelayed();
64
67
  };
65
68
  history.replaceState = function(...args) {
66
69
  originalReplaceState.apply(this, args);
67
- capturePageview();
70
+ capturePageviewDelayed();
68
71
  };
69
72
  }
70
73
  var formCallback = null;
@@ -115,6 +118,431 @@ function stopAutocapture() {
115
118
  document.removeEventListener("submit", handleFormSubmit, true);
116
119
  }
117
120
 
121
+ // src/embed-integrations.ts
122
+ var callbacks = null;
123
+ var isListening = false;
124
+ var calSetupAttempts = 0;
125
+ var calCallbackRegistered = false;
126
+ var lastBookingUid = null;
127
+ var CAL_MAX_RETRY_ATTEMPTS = 10;
128
+ var CAL_INITIAL_DELAY_MS = 200;
129
+ var CAL_MAX_DELAY_MS = 2e3;
130
+ function parseCalComBooking(data) {
131
+ const event = {
132
+ provider: "cal.com"
133
+ };
134
+ if (data.title) {
135
+ event.eventType = data.title;
136
+ const nameMatch = data.title.match(/between .+ and (.+)$/i);
137
+ if (nameMatch?.[1]) {
138
+ event.inviteeName = nameMatch[1].trim();
139
+ }
140
+ }
141
+ if (data.startTime) event.startTime = data.startTime;
142
+ if (data.endTime) event.endTime = data.endTime;
143
+ if (data.startTime && data.endTime) {
144
+ const start = new Date(data.startTime);
145
+ const end = new Date(data.endTime);
146
+ event.duration = Math.round((end.getTime() - start.getTime()) / 6e4);
147
+ }
148
+ if (data.isRecurring !== void 0) {
149
+ event.isRecurring = data.isRecurring;
150
+ }
151
+ return event;
152
+ }
153
+ function setupCalComListener() {
154
+ if (typeof window === "undefined") return;
155
+ if (calCallbackRegistered) return;
156
+ calSetupAttempts++;
157
+ if ("Cal" in window) {
158
+ const Cal = window.Cal;
159
+ if (typeof Cal === "function") {
160
+ try {
161
+ Cal("on", {
162
+ action: "bookingSuccessfulV2",
163
+ callback: handleCalComBooking
164
+ });
165
+ calCallbackRegistered = true;
166
+ return;
167
+ } catch (_e) {
168
+ }
169
+ }
170
+ }
171
+ if (calSetupAttempts < CAL_MAX_RETRY_ATTEMPTS) {
172
+ const delay = Math.min(CAL_INITIAL_DELAY_MS * calSetupAttempts, CAL_MAX_DELAY_MS);
173
+ setTimeout(setupCalComListener, delay);
174
+ }
175
+ }
176
+ function handleCalComBooking(e) {
177
+ if (!callbacks) return;
178
+ const data = e.detail?.data;
179
+ if (!data) return;
180
+ if (data.uid && data.uid === lastBookingUid) return;
181
+ lastBookingUid = data.uid || null;
182
+ const bookingEvent = parseCalComBooking(data);
183
+ callbacks.onCalendarBooked(bookingEvent);
184
+ }
185
+ function handlePostMessage(event) {
186
+ if (!callbacks) return;
187
+ if (isCalendlyEvent(event)) {
188
+ if (event.data.event === "calendly.event_scheduled") {
189
+ const bookingEvent = parseCalendlyBooking(event.data.payload);
190
+ callbacks.onCalendarBooked(bookingEvent);
191
+ }
192
+ return;
193
+ }
194
+ if (isCalComRawMessage(event)) {
195
+ const bookingData = extractCalComBookingFromMessage(event.data);
196
+ if (bookingData) {
197
+ if (bookingData.uid && bookingData.uid === lastBookingUid) return;
198
+ lastBookingUid = bookingData.uid || null;
199
+ const bookingEvent = parseCalComBooking(bookingData);
200
+ callbacks.onCalendarBooked(bookingEvent);
201
+ }
202
+ }
203
+ }
204
+ function isCalComRawMessage(event) {
205
+ if (!event.origin.includes("cal.com")) return false;
206
+ const data = event.data;
207
+ if (!data || typeof data !== "object") return false;
208
+ const messageType = data.type || data.action;
209
+ return messageType === "bookingSuccessfulV2" || messageType === "bookingSuccessful" || messageType === "booking_successful";
210
+ }
211
+ function extractCalComBookingFromMessage(data) {
212
+ if (!data || typeof data !== "object") return null;
213
+ const messageData = data;
214
+ if (messageData.data && typeof messageData.data === "object") {
215
+ return messageData.data;
216
+ }
217
+ if (messageData.booking && typeof messageData.booking === "object") {
218
+ return messageData.booking;
219
+ }
220
+ return null;
221
+ }
222
+ function isCalendlyEvent(e) {
223
+ return e.origin === "https://calendly.com" && e.data && typeof e.data.event === "string" && e.data.event.startsWith("calendly.");
224
+ }
225
+ function parseCalendlyBooking(_payload) {
226
+ return {
227
+ provider: "calendly"
228
+ };
229
+ }
230
+ function initCalendarTracking(cbs) {
231
+ if (isListening) return;
232
+ callbacks = cbs;
233
+ isListening = true;
234
+ calSetupAttempts = 0;
235
+ window.addEventListener("message", handlePostMessage);
236
+ setupCalComListener();
237
+ }
238
+ function stopCalendarTracking() {
239
+ if (!isListening) return;
240
+ window.removeEventListener("message", handlePostMessage);
241
+ callbacks = null;
242
+ isListening = false;
243
+ calCallbackRegistered = false;
244
+ calSetupAttempts = 0;
245
+ lastBookingUid = null;
246
+ }
247
+
248
+ // src/session-tracker.ts
249
+ var import_core2 = require("@outlit/core");
250
+ var DEFAULT_IDLE_TIMEOUT = 3e4;
251
+ var SESSION_TIMEOUT = 30 * 60 * 1e3;
252
+ var TIME_UPDATE_INTERVAL = 1e3;
253
+ var MIN_SPURIOUS_THRESHOLD = 50;
254
+ var SESSION_ID_KEY = "outlit_session_id";
255
+ var SESSION_LAST_ACTIVITY_KEY = "outlit_session_last_activity";
256
+ var SessionTracker = class {
257
+ state;
258
+ options;
259
+ idleTimeout;
260
+ timeUpdateInterval = null;
261
+ boundHandleActivity;
262
+ boundHandleVisibilityChange;
263
+ constructor(options) {
264
+ this.options = options;
265
+ this.idleTimeout = options.idleTimeout ?? DEFAULT_IDLE_TIMEOUT;
266
+ this.state = this.createInitialState();
267
+ this.boundHandleActivity = this.handleActivity.bind(this);
268
+ this.boundHandleVisibilityChange = this.handleVisibilityChange.bind(this);
269
+ this.setupEventListeners();
270
+ this.startTimeUpdateInterval();
271
+ }
272
+ /**
273
+ * Get the current session ID.
274
+ */
275
+ getSessionId() {
276
+ return this.state.sessionId;
277
+ }
278
+ // ============================================
279
+ // PUBLIC METHODS
280
+ // ============================================
281
+ /**
282
+ * Emit an engagement event for the current page session.
283
+ * Called by Tracker on exit events and SPA navigation.
284
+ *
285
+ * This method:
286
+ * 1. Finalizes any pending active time
287
+ * 2. Creates and emits the engagement event (if meaningful)
288
+ * 3. Resets state for the next session
289
+ */
290
+ emitEngagement() {
291
+ if (this.state.hasEmittedEngagement) {
292
+ return;
293
+ }
294
+ this.state.hasEmittedEngagement = true;
295
+ this.updateActiveTime();
296
+ const totalTimeMs = Date.now() - this.state.pageEntryTime;
297
+ const isSpuriousEvent = this.state.activeTimeMs < MIN_SPURIOUS_THRESHOLD && totalTimeMs < MIN_SPURIOUS_THRESHOLD;
298
+ if (!isSpuriousEvent) {
299
+ const event = (0, import_core2.buildEngagementEvent)({
300
+ url: this.state.currentUrl,
301
+ referrer: document.referrer,
302
+ activeTimeMs: this.state.activeTimeMs,
303
+ totalTimeMs,
304
+ sessionId: this.state.sessionId
305
+ });
306
+ this.options.onEngagement(event);
307
+ }
308
+ this.resetState();
309
+ }
310
+ /**
311
+ * Handle SPA navigation.
312
+ * Called by Tracker when a new pageview is detected.
313
+ *
314
+ * This method:
315
+ * 1. Emits engagement for the OLD page (using stored state)
316
+ * 2. Updates state for the NEW page
317
+ */
318
+ onNavigation(newUrl) {
319
+ this.emitEngagement();
320
+ this.state.currentUrl = newUrl;
321
+ this.state.currentPath = this.extractPath(newUrl);
322
+ this.state.pageEntryTime = Date.now();
323
+ this.state.activeTimeMs = 0;
324
+ this.state.lastActiveTime = Date.now();
325
+ this.state.isUserActive = true;
326
+ this.state.hasEmittedEngagement = false;
327
+ this.resetIdleTimer();
328
+ }
329
+ /**
330
+ * Stop session tracking and clean up.
331
+ */
332
+ stop() {
333
+ this.removeEventListeners();
334
+ if (this.timeUpdateInterval) {
335
+ clearInterval(this.timeUpdateInterval);
336
+ this.timeUpdateInterval = null;
337
+ }
338
+ if (this.state.idleTimeoutId) {
339
+ clearTimeout(this.state.idleTimeoutId);
340
+ this.state.idleTimeoutId = null;
341
+ }
342
+ }
343
+ // ============================================
344
+ // PRIVATE METHODS
345
+ // ============================================
346
+ createInitialState() {
347
+ const now = Date.now();
348
+ return {
349
+ currentUrl: typeof window !== "undefined" ? window.location.href : "",
350
+ currentPath: typeof window !== "undefined" ? window.location.pathname : "/",
351
+ pageEntryTime: now,
352
+ lastActiveTime: now,
353
+ activeTimeMs: 0,
354
+ isPageVisible: typeof document !== "undefined" ? document.visibilityState === "visible" : true,
355
+ isUserActive: true,
356
+ // Assume active on page load
357
+ idleTimeoutId: null,
358
+ sessionId: this.getOrCreateSessionId(),
359
+ hasEmittedEngagement: false
360
+ };
361
+ }
362
+ resetState() {
363
+ const now = Date.now();
364
+ this.state.pageEntryTime = now;
365
+ this.state.lastActiveTime = now;
366
+ this.state.activeTimeMs = 0;
367
+ this.state.isUserActive = true;
368
+ this.resetIdleTimer();
369
+ }
370
+ /**
371
+ * Get existing session ID from storage or create a new one.
372
+ * Session ID is reset if:
373
+ * - No existing session ID in storage
374
+ * - Last activity was more than 30 minutes ago
375
+ */
376
+ getOrCreateSessionId() {
377
+ if (typeof sessionStorage === "undefined") {
378
+ return this.generateSessionId();
379
+ }
380
+ try {
381
+ const existingSessionId = sessionStorage.getItem(SESSION_ID_KEY);
382
+ const lastActivityStr = sessionStorage.getItem(SESSION_LAST_ACTIVITY_KEY);
383
+ const lastActivity = lastActivityStr ? Number.parseInt(lastActivityStr, 10) : 0;
384
+ const now = Date.now();
385
+ if (existingSessionId && lastActivity && now - lastActivity < SESSION_TIMEOUT) {
386
+ this.updateSessionActivity();
387
+ return existingSessionId;
388
+ }
389
+ const newSessionId = this.generateSessionId();
390
+ sessionStorage.setItem(SESSION_ID_KEY, newSessionId);
391
+ sessionStorage.setItem(SESSION_LAST_ACTIVITY_KEY, now.toString());
392
+ return newSessionId;
393
+ } catch {
394
+ return this.generateSessionId();
395
+ }
396
+ }
397
+ /**
398
+ * Generate a new session ID (UUID v4).
399
+ */
400
+ generateSessionId() {
401
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
402
+ return crypto.randomUUID();
403
+ }
404
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
405
+ const r = Math.random() * 16 | 0;
406
+ const v = c === "x" ? r : r & 3 | 8;
407
+ return v.toString(16);
408
+ });
409
+ }
410
+ /**
411
+ * Update the session's last activity timestamp.
412
+ */
413
+ updateSessionActivity() {
414
+ if (typeof sessionStorage === "undefined") return;
415
+ try {
416
+ sessionStorage.setItem(SESSION_LAST_ACTIVITY_KEY, Date.now().toString());
417
+ } catch {
418
+ }
419
+ }
420
+ /**
421
+ * Check if the current session has expired and create a new one if needed.
422
+ * Called when user returns to the page after being away.
423
+ */
424
+ checkSessionExpiry() {
425
+ if (typeof sessionStorage === "undefined") return;
426
+ try {
427
+ const lastActivityStr = sessionStorage.getItem(SESSION_LAST_ACTIVITY_KEY);
428
+ const lastActivity = lastActivityStr ? Number.parseInt(lastActivityStr, 10) : 0;
429
+ const now = Date.now();
430
+ if (now - lastActivity >= SESSION_TIMEOUT) {
431
+ const newSessionId = this.generateSessionId();
432
+ sessionStorage.setItem(SESSION_ID_KEY, newSessionId);
433
+ this.state.sessionId = newSessionId;
434
+ }
435
+ sessionStorage.setItem(SESSION_LAST_ACTIVITY_KEY, now.toString());
436
+ } catch {
437
+ }
438
+ }
439
+ setupEventListeners() {
440
+ if (typeof window === "undefined" || typeof document === "undefined") return;
441
+ const activityEvents = ["mousemove", "keydown", "click", "scroll", "touchstart"];
442
+ for (const event of activityEvents) {
443
+ document.addEventListener(event, this.boundHandleActivity, { passive: true });
444
+ }
445
+ document.addEventListener("visibilitychange", this.boundHandleVisibilityChange);
446
+ this.resetIdleTimer();
447
+ }
448
+ removeEventListeners() {
449
+ if (typeof window === "undefined" || typeof document === "undefined") return;
450
+ const activityEvents = ["mousemove", "keydown", "click", "scroll", "touchstart"];
451
+ for (const event of activityEvents) {
452
+ document.removeEventListener(event, this.boundHandleActivity);
453
+ }
454
+ document.removeEventListener("visibilitychange", this.boundHandleVisibilityChange);
455
+ }
456
+ /**
457
+ * Handle user activity events.
458
+ * Marks user as active and resets idle timer.
459
+ */
460
+ handleActivity() {
461
+ if (!this.state.isUserActive) {
462
+ this.checkSessionExpiry();
463
+ this.state.lastActiveTime = Date.now();
464
+ }
465
+ this.state.isUserActive = true;
466
+ this.resetIdleTimer();
467
+ this.updateSessionActivity();
468
+ }
469
+ /**
470
+ * Handle visibility change events.
471
+ * Pauses time accumulation when tab is hidden.
472
+ */
473
+ handleVisibilityChange() {
474
+ const wasVisible = this.state.isPageVisible;
475
+ const isNowVisible = document.visibilityState === "visible";
476
+ if (wasVisible && !isNowVisible) {
477
+ this.updateActiveTime();
478
+ }
479
+ this.state.isPageVisible = isNowVisible;
480
+ if (!wasVisible && isNowVisible) {
481
+ this.checkSessionExpiry();
482
+ this.state.lastActiveTime = Date.now();
483
+ this.state.hasEmittedEngagement = false;
484
+ }
485
+ }
486
+ /**
487
+ * Reset the idle timer.
488
+ * Called on activity and initialization.
489
+ */
490
+ resetIdleTimer() {
491
+ if (this.state.idleTimeoutId) {
492
+ clearTimeout(this.state.idleTimeoutId);
493
+ }
494
+ this.state.idleTimeoutId = setTimeout(() => {
495
+ this.updateActiveTime();
496
+ this.state.isUserActive = false;
497
+ }, this.idleTimeout);
498
+ }
499
+ /**
500
+ * Start the interval for updating active time.
501
+ */
502
+ startTimeUpdateInterval() {
503
+ if (this.timeUpdateInterval) return;
504
+ this.timeUpdateInterval = setInterval(() => {
505
+ this.updateActiveTime();
506
+ }, TIME_UPDATE_INTERVAL);
507
+ }
508
+ /**
509
+ * Update accumulated active time.
510
+ * Only accumulates when page is visible AND user is active.
511
+ */
512
+ updateActiveTime() {
513
+ if (this.state.isPageVisible && this.state.isUserActive) {
514
+ const now = Date.now();
515
+ this.state.activeTimeMs += now - this.state.lastActiveTime;
516
+ this.state.lastActiveTime = now;
517
+ }
518
+ }
519
+ /**
520
+ * Extract path from URL.
521
+ */
522
+ extractPath(url) {
523
+ try {
524
+ return new URL(url).pathname;
525
+ } catch {
526
+ return "/";
527
+ }
528
+ }
529
+ };
530
+ var sessionTrackerInstance = null;
531
+ function initSessionTracking(options) {
532
+ if (sessionTrackerInstance) {
533
+ console.warn("[Outlit] Session tracking already initialized");
534
+ return sessionTrackerInstance;
535
+ }
536
+ sessionTrackerInstance = new SessionTracker(options);
537
+ return sessionTrackerInstance;
538
+ }
539
+ function stopSessionTracking() {
540
+ if (sessionTrackerInstance) {
541
+ sessionTrackerInstance.stop();
542
+ sessionTrackerInstance = null;
543
+ }
544
+ }
545
+
118
546
  // src/storage.ts
119
547
  var VISITOR_ID_KEY = "outlit_visitor_id";
120
548
  function generateVisitorId() {
@@ -196,7 +624,7 @@ function setCookie(name, value, days) {
196
624
  }
197
625
 
198
626
  // src/tracker.ts
199
- var Tracker = class {
627
+ var Outlit = class {
200
628
  publicKey;
201
629
  apiHost;
202
630
  visitorId = null;
@@ -206,15 +634,29 @@ var Tracker = class {
206
634
  isInitialized = false;
207
635
  isTrackingEnabled = false;
208
636
  options;
637
+ hasHandledExit = false;
638
+ sessionTracker = null;
209
639
  constructor(options) {
210
640
  this.publicKey = options.publicKey;
211
- this.apiHost = options.apiHost ?? import_core2.DEFAULT_API_HOST;
641
+ this.apiHost = options.apiHost ?? import_core3.DEFAULT_API_HOST;
212
642
  this.flushInterval = options.flushInterval ?? 5e3;
213
643
  this.options = options;
214
644
  if (typeof window !== "undefined") {
215
- window.addEventListener("beforeunload", () => {
645
+ const handleExit = () => {
646
+ if (this.hasHandledExit) return;
647
+ this.hasHandledExit = true;
648
+ this.sessionTracker?.emitEngagement();
216
649
  this.flush();
650
+ };
651
+ document.addEventListener("visibilitychange", () => {
652
+ if (document.visibilityState === "hidden") {
653
+ handleExit();
654
+ } else {
655
+ this.hasHandledExit = false;
656
+ }
217
657
  });
658
+ window.addEventListener("pagehide", handleExit);
659
+ window.addEventListener("beforeunload", handleExit);
218
660
  }
219
661
  this.isInitialized = true;
220
662
  if (options.autoTrack !== false) {
@@ -239,12 +681,18 @@ var Tracker = class {
239
681
  }
240
682
  this.visitorId = getOrCreateVisitorId();
241
683
  this.startFlushTimer();
684
+ if (this.options.trackEngagement !== false) {
685
+ this.initSessionTracking();
686
+ }
242
687
  if (this.options.trackPageviews !== false) {
243
688
  this.initPageviewTracking();
244
689
  }
245
690
  if (this.options.trackForms !== false) {
246
691
  this.initFormTracking(this.options.formFieldDenylist);
247
692
  }
693
+ if (this.options.trackCalendarEmbeds !== false) {
694
+ this.initCalendarTracking();
695
+ }
248
696
  this.isTrackingEnabled = true;
249
697
  }
250
698
  /**
@@ -261,7 +709,7 @@ var Tracker = class {
261
709
  console.warn("[Outlit] Tracking not enabled. Call enableTracking() first.");
262
710
  return;
263
711
  }
264
- const event = (0, import_core2.buildCustomEvent)({
712
+ const event = (0, import_core3.buildCustomEvent)({
265
713
  url: window.location.href,
266
714
  referrer: document.referrer,
267
715
  eventName,
@@ -278,7 +726,7 @@ var Tracker = class {
278
726
  console.warn("[Outlit] Tracking not enabled. Call enableTracking() first.");
279
727
  return;
280
728
  }
281
- const event = (0, import_core2.buildIdentifyEvent)({
729
+ const event = (0, import_core3.buildIdentifyEvent)({
282
730
  url: window.location.href,
283
731
  referrer: document.referrer,
284
732
  email: options.email,
@@ -304,7 +752,7 @@ var Tracker = class {
304
752
  await this.sendEvents(events);
305
753
  }
306
754
  /**
307
- * Shutdown the tracker.
755
+ * Shutdown the client.
308
756
  */
309
757
  async shutdown() {
310
758
  if (this.flushTimer) {
@@ -312,14 +760,26 @@ var Tracker = class {
312
760
  this.flushTimer = null;
313
761
  }
314
762
  stopAutocapture();
763
+ stopCalendarTracking();
764
+ stopSessionTracking();
765
+ this.sessionTracker = null;
315
766
  await this.flush();
316
767
  }
317
768
  // ============================================
318
769
  // INTERNAL METHODS
319
770
  // ============================================
771
+ initSessionTracking() {
772
+ this.sessionTracker = initSessionTracking({
773
+ onEngagement: (event) => {
774
+ this.enqueue(event);
775
+ },
776
+ idleTimeout: this.options.idleTimeout
777
+ });
778
+ }
320
779
  initPageviewTracking() {
321
780
  initPageviewTracking((url, referrer, title) => {
322
- const event = (0, import_core2.buildPageviewEvent)({ url, referrer, title });
781
+ this.sessionTracker?.onNavigation(url);
782
+ const event = (0, import_core3.buildPageviewEvent)({ url, referrer, title });
323
783
  this.enqueue(event);
324
784
  });
325
785
  }
@@ -336,7 +796,7 @@ var Tracker = class {
336
796
  } : void 0;
337
797
  initFormTracking(
338
798
  (url, formId, fields) => {
339
- const event = (0, import_core2.buildFormEvent)({
799
+ const event = (0, import_core3.buildFormEvent)({
340
800
  url,
341
801
  referrer: document.referrer,
342
802
  formId,
@@ -348,6 +808,25 @@ var Tracker = class {
348
808
  identityCallback2
349
809
  );
350
810
  }
811
+ initCalendarTracking() {
812
+ initCalendarTracking({
813
+ onCalendarBooked: (bookingEvent) => {
814
+ const event = (0, import_core3.buildCalendarEvent)({
815
+ url: window.location.href,
816
+ referrer: document.referrer,
817
+ provider: bookingEvent.provider,
818
+ eventType: bookingEvent.eventType,
819
+ startTime: bookingEvent.startTime,
820
+ endTime: bookingEvent.endTime,
821
+ duration: bookingEvent.duration,
822
+ isRecurring: bookingEvent.isRecurring,
823
+ inviteeEmail: bookingEvent.inviteeEmail,
824
+ inviteeName: bookingEvent.inviteeName
825
+ });
826
+ this.enqueue(event);
827
+ }
828
+ });
829
+ }
351
830
  enqueue(event) {
352
831
  this.eventQueue.push(event);
353
832
  if (this.eventQueue.length >= 10) {
@@ -363,7 +842,7 @@ var Tracker = class {
363
842
  async sendEvents(events) {
364
843
  if (events.length === 0) return;
365
844
  if (!this.visitorId) return;
366
- const payload = (0, import_core2.buildIngestPayload)(this.visitorId, "pixel", events);
845
+ const payload = (0, import_core3.buildIngestPayload)(this.visitorId, "client", events);
367
846
  const url = `${this.apiHost}/api/i/v1/${this.publicKey}/events`;
368
847
  try {
369
848
  if (typeof navigator !== "undefined" && navigator.sendBeacon) {
@@ -388,7 +867,7 @@ var Tracker = class {
388
867
  // src/react/provider.tsx
389
868
  var import_jsx_runtime = require("react/jsx-runtime");
390
869
  var OutlitContext = (0, import_react.createContext)({
391
- tracker: null,
870
+ outlit: null,
392
871
  isInitialized: false,
393
872
  isTrackingEnabled: false,
394
873
  enableTracking: () => {
@@ -405,12 +884,12 @@ function OutlitProvider({
405
884
  autoTrack = true,
406
885
  autoIdentify = true
407
886
  }) {
408
- const trackerRef = (0, import_react.useRef)(null);
887
+ const outlitRef = (0, import_react.useRef)(null);
409
888
  const initializedRef = (0, import_react.useRef)(false);
410
889
  const [isTrackingEnabled, setIsTrackingEnabled] = (0, import_react.useState)(false);
411
890
  (0, import_react.useEffect)(() => {
412
891
  if (initializedRef.current) return;
413
- trackerRef.current = new Tracker({
892
+ outlitRef.current = new Outlit({
414
893
  publicKey,
415
894
  apiHost,
416
895
  trackPageviews,
@@ -421,9 +900,9 @@ function OutlitProvider({
421
900
  autoIdentify
422
901
  });
423
902
  initializedRef.current = true;
424
- setIsTrackingEnabled(trackerRef.current.isEnabled());
903
+ setIsTrackingEnabled(outlitRef.current.isEnabled());
425
904
  return () => {
426
- trackerRef.current?.shutdown();
905
+ outlitRef.current?.shutdown();
427
906
  };
428
907
  }, [
429
908
  publicKey,
@@ -436,8 +915,8 @@ function OutlitProvider({
436
915
  autoIdentify
437
916
  ]);
438
917
  const enableTracking = (0, import_react.useCallback)(() => {
439
- if (trackerRef.current) {
440
- trackerRef.current.enableTracking();
918
+ if (outlitRef.current) {
919
+ outlitRef.current.enableTracking();
441
920
  setIsTrackingEnabled(true);
442
921
  }
443
922
  }, []);
@@ -445,7 +924,7 @@ function OutlitProvider({
445
924
  OutlitContext.Provider,
446
925
  {
447
926
  value: {
448
- tracker: trackerRef.current,
927
+ outlit: outlitRef.current,
449
928
  isInitialized: initializedRef.current,
450
929
  isTrackingEnabled,
451
930
  enableTracking
@@ -458,31 +937,31 @@ function OutlitProvider({
458
937
  // src/react/hooks.ts
459
938
  var import_react2 = require("react");
460
939
  function useOutlit() {
461
- const { tracker, isInitialized, isTrackingEnabled, enableTracking } = (0, import_react2.useContext)(OutlitContext);
940
+ const { outlit, isInitialized, isTrackingEnabled, enableTracking } = (0, import_react2.useContext)(OutlitContext);
462
941
  const track = (0, import_react2.useCallback)(
463
942
  (eventName, properties) => {
464
- if (!tracker) {
465
- console.warn("[Outlit] Tracker not initialized. Make sure OutlitProvider is mounted.");
943
+ if (!outlit) {
944
+ console.warn("[Outlit] Not initialized. Make sure OutlitProvider is mounted.");
466
945
  return;
467
946
  }
468
- tracker.track(eventName, properties);
947
+ outlit.track(eventName, properties);
469
948
  },
470
- [tracker]
949
+ [outlit]
471
950
  );
472
951
  const identify = (0, import_react2.useCallback)(
473
952
  (options) => {
474
- if (!tracker) {
475
- console.warn("[Outlit] Tracker not initialized. Make sure OutlitProvider is mounted.");
953
+ if (!outlit) {
954
+ console.warn("[Outlit] Not initialized. Make sure OutlitProvider is mounted.");
476
955
  return;
477
956
  }
478
- tracker.identify(options);
957
+ outlit.identify(options);
479
958
  },
480
- [tracker]
959
+ [outlit]
481
960
  );
482
961
  const getVisitorId = (0, import_react2.useCallback)(() => {
483
- if (!tracker) return null;
484
- return tracker.getVisitorId();
485
- }, [tracker]);
962
+ if (!outlit) return null;
963
+ return outlit.getVisitorId();
964
+ }, [outlit]);
486
965
  return {
487
966
  track,
488
967
  identify,