// src/constants.ts
var SDK_API_PATH = `/v1`;
var SDK_PLATFORM = typeof window !== "undefined" ? "browser" : typeof process !== "undefined" && process.versions?.node ? "node" : "unknown";
var SESSION_TOKEN_LIFETIME_SECONDS = 5 * 60;
var SESSION_TOKEN_LIFETIME_MS = SESSION_TOKEN_LIFETIME_SECONDS * 1e3;
var REFRESH_TOKEN_LIFETIME_SECONDS = 30 * 24 * 60 * 60;
var FLAGS_CACHE_TTL_MS = 5 * 60 * 1e3;
var FLAGS_STALE_WHILE_REVALIDATE_MS = 60 * 1e3;
var ANALYTICS_SESSION_TIMEOUT_MS = 30 * 60 * 1e3;
var WEBHOOK_MAX_AGE_MS = 5 * 60 * 1e3;
var WEBHOOK_CLOCK_SKEW_MS = 30 * 1e3;
var PKCE_CODE_TTL_MS = 10 * 60 * 1e3;
var JOBS_DLQ_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
var SESSION_REPLAY_MAX_DURATION_MS = 60 * 60 * 1e3;
var FLAGS_EXPOSURE_DEDUPE_WINDOW_MS = 60 * 60 * 1e3;
var CLICK_ID_EXPIRY_MS = 90 * 24 * 60 * 60 * 1e3;
var STALE_TIME_FREQUENT_MS = 60 * 1e3;
var STALE_TIME_MODERATE_MS = 2 * 60 * 1e3;
var STALE_TIME_STABLE_MS = 5 * 60 * 1e3;
var STALE_TIME_STATS_MS = 30 * 1e3;
var NEW_USER_THRESHOLD_MS = 60 * 1e3;
var STORAGE_MULTIPART_THRESHOLD_BYTES = 5 * 1024 * 1024;
var STORAGE_DEFAULT_MAX_SIZE_BYTES = 5 * 1024 * 1024;
var STORAGE_AVATAR_MAX_SIZE_BYTES = 2 * 1024 * 1024;
var STORAGE_LARGE_MAX_SIZE_BYTES = 10 * 1024 * 1024;
var JWK_CACHE_TTL_MS = 60 * 60 * 1e3;
var ETAG_CACHE_TTL_MS = 5 * 60 * 1e3;

// src/lib/analytics/web-analytics.ts
function generateSessionId() {
  if (typeof crypto !== "undefined" && crypto.randomUUID) {
    return crypto.randomUUID();
  }
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
    const r = Math.random() * 16 | 0;
    const v = c === "x" ? r : r & 3 | 8;
    return v.toString(16);
  });
}
function getOrCreateSessionId() {
  if (typeof sessionStorage === "undefined") return generateSessionId();
  const key = "_sylphx_sid";
  let id = sessionStorage.getItem(key);
  if (!id) {
    id = generateSessionId();
    sessionStorage.setItem(key, id);
  }
  return id;
}
function getCurrentPath(hashMode) {
  if (typeof window === "undefined" || !window.location) return "/";
  if (hashMode) {
    return window.location.hash.replace(/^#/, "") || "/";
  }
  return window.location.pathname + window.location.search;
}
var WebAnalyticsTracker = class {
  options = null;
  initialized = false;
  lastPath = null;
  // biome-ignore lint/correctness/noUnusedPrivateClassMembers: used in trackPageView
  pageViewCount = 0;
  cleanupFns = [];
  /**
   * Initialize the tracker and start auto-tracking page views
   */
  init(options) {
    if (typeof window === "undefined") return;
    if (this.initialized) return;
    this.options = {
      trackPageViews: true,
      trackBounce: true,
      hashMode: false,
      debug: false,
      ...options
    };
    this.initialized = true;
    if (this.options.trackPageViews) {
      this.trackPageView();
      this._hookNextRouter();
      if (this.options.hashMode) {
        const onHashChange = () => this.trackPageView();
        window.addEventListener("hashchange", onHashChange);
        this.cleanupFns.push(() => window.removeEventListener("hashchange", onHashChange));
      }
      this._hookHistoryApi();
    }
    if (this.options.debug) {
    }
  }
  /**
   * Manually track a page view
   */
  trackPageView(path) {
    if (!this.options) return;
    if (typeof window === "undefined") return;
    const currentPath = path ?? getCurrentPath(this.options.hashMode);
    if (currentPath === this.lastPath) return;
    this.lastPath = currentPath;
    this.pageViewCount++;
    const payload = {
      path: currentPath,
      referrer: typeof document !== "undefined" ? document.referrer || "" : "",
      userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "",
      screenWidth: window.screen?.width,
      sessionId: getOrCreateSessionId(),
      timestamp: Date.now()
    };
    if (this.options.debug) {
    }
    this._send(`${SDK_API_PATH}/analytics/pageview`, payload);
  }
  /**
   * Identify a user
   */
  identify(userId, traits) {
    if (!this.options) return;
    if (typeof window === "undefined") return;
    const payload = {
      userId,
      traits,
      sessionId: getOrCreateSessionId()
    };
    if (this.options.debug) {
    }
    this._send(`${SDK_API_PATH}/analytics/identify`, payload);
  }
  /**
   * Destroy the tracker and remove event listeners
   */
  destroy() {
    for (const fn of this.cleanupFns) {
      fn();
    }
    this.cleanupFns = [];
    this.initialized = false;
    this.options = null;
    this.lastPath = null;
    this.pageViewCount = 0;
  }
  // ==========================================
  // Private helpers
  // ==========================================
  _send(path, payload) {
    if (!this.options) return;
    const url = `${this.options.endpoint}${path}`;
    const data = JSON.stringify(payload);
    try {
      if (typeof navigator !== "undefined" && navigator.sendBeacon) {
        const blob = new Blob([data], { type: "application/json" });
        const sent = navigator.sendBeacon(url, blob);
        if (!sent && this.options.debug) {
          console.warn("[WebAnalytics] sendBeacon failed, falling back to fetch");
        }
        if (sent) return;
      }
      fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-app-key": this.options.appKey
        },
        body: data,
        keepalive: true
      }).catch((err) => {
        if (this.options?.debug) {
          console.error("[WebAnalytics] Failed to send:", err);
        }
      });
    } catch (err) {
      if (this.options?.debug) {
        console.error("[WebAnalytics] Send error:", err);
      }
    }
  }
  _hookHistoryApi() {
    if (typeof window === "undefined") return;
    const originalPush = window.history.pushState.bind(window.history);
    const originalReplace = window.history.replaceState.bind(window.history);
    window.history.pushState = (...args) => {
      originalPush(...args);
      setTimeout(() => this.trackPageView(), 0);
    };
    window.history.replaceState = (...args) => {
      originalReplace(...args);
    };
    const onPopState = () => setTimeout(() => this.trackPageView(), 0);
    window.addEventListener("popstate", onPopState);
    this.cleanupFns.push(() => {
      window.history.pushState = originalPush;
      window.history.replaceState = originalReplace;
      window.removeEventListener("popstate", onPopState);
    });
  }
  _hookNextRouter() {
    if (typeof document === "undefined") return;
    const onRouteAnnounced = () => setTimeout(() => this.trackPageView(), 0);
    document.addEventListener("nextjs:route-announced", onRouteAnnounced);
    this.cleanupFns.push(() => {
      document.removeEventListener("nextjs:route-announced", onRouteAnnounced);
    });
  }
};
var _tracker = null;
function getWebAnalyticsTracker() {
  if (!_tracker) {
    _tracker = new WebAnalyticsTracker();
  }
  return _tracker;
}
function initWebAnalytics(options) {
  getWebAnalyticsTracker().init(options);
}
export {
  WebAnalyticsTracker,
  getWebAnalyticsTracker,
  initWebAnalytics
};
//# sourceMappingURL=web-analytics.mjs.map