{"version":3,"sources":["../src/utils/MouseTracker.ts","../src/utils/CursorCoordinator.ts"],"names":["_MouseTracker","subscription","isSSR","subscriberState","id","event","newPosition","currentTime","lastCallTime","timeoutId","throttleMs","timeSinceLastCall","stored","e","__spreadValues","MouseTracker","_CursorCoordinator","mouseUnsubscribe","position","subscriptionId","CursorCoordinator"],"mappings":"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","file":"CursorCoordinator-M32HDHIO.mjs","sourcesContent":["import { isSSR } from './ssr';\n\n// Types for the mouse tracker\nexport interface MouseSubscription {\n  id: string;\n  callback: (position: { x: number; y: number }) => void;\n  throttleMs?: number;\n}\n\ninterface SubscriberState {\n  subscription: MouseSubscription;\n  lastCallTime: number;\n  timeoutId: NodeJS.Timeout | null;\n}\n\nclass MouseTracker {\n  private static instance: MouseTracker | null = null;\n  private subscribers = new Map<string, SubscriberState>();\n  private currentPosition: { x: number; y: number } | null = null;\n  private isListening = false;\n  private rafId: number | null = null;\n\n  private constructor() {\n    this.handleMouseMove = this.handleMouseMove.bind(this);\n  }\n\n  static getInstance(): MouseTracker {\n    if (!MouseTracker.instance) {\n      MouseTracker.instance = new MouseTracker();\n    }\n    return MouseTracker.instance;\n  }\n\n  subscribe(subscription: MouseSubscription): () => void {\n    // Skip subscription during SSR\n    if (isSSR()) {\n      // eslint-disable-next-line @typescript-eslint/no-empty-function\n      return () => {}; // No-op cleanup\n    }\n\n    const subscriberState: SubscriberState = {\n      subscription,\n      lastCallTime: 0,\n      timeoutId: null,\n    };\n\n    this.subscribers.set(subscription.id, subscriberState);\n    \n    // Start listening if this is the first subscriber\n    if (!this.isListening) {\n      this.startListening();\n    }\n\n    // Immediately notify new subscriber if we have a current position\n    if (this.currentPosition) {\n      // Use setTimeout to avoid synchronous callback during subscription\n      setTimeout(() => {\n        if (this.subscribers.has(subscription.id)) {\n          this.callSubscriber(subscriberState);\n        }\n      }, 0);\n    }\n\n    // Return unsubscribe function\n    return () => {\n      this.unsubscribe(subscription.id);\n    };\n  }\n\n  private unsubscribe(id: string): void {\n    const subscriberState = this.subscribers.get(id);\n    if (subscriberState?.timeoutId) {\n      clearTimeout(subscriberState.timeoutId);\n    }\n    \n    this.subscribers.delete(id);\n    \n    // Stop listening if no more subscribers\n    if (this.subscribers.size === 0) {\n      this.stopListening();\n    }\n  }\n\n  private startListening(): void {\n    if (this.isListening || isSSR()) return;\n    \n    document.addEventListener('mousemove', this.handleMouseMove);\n    this.isListening = true;\n    \n    // Store position globally for persistence across navigation\n    this.loadGlobalPosition();\n  }\n\n  private stopListening(): void {\n    if (!this.isListening) return;\n    \n    document.removeEventListener('mousemove', this.handleMouseMove);\n    this.isListening = false;\n    \n    if (this.rafId) {\n      cancelAnimationFrame(this.rafId);\n      this.rafId = null;\n    }\n  }\n\n  private handleMouseMove(event: MouseEvent): void {\n    const newPosition = { x: event.clientX, y: event.clientY };\n    \n    this.currentPosition = newPosition;\n    this.saveGlobalPosition();\n    \n    // Use RAF to batch notifications for better performance\n    if (this.rafId === null) {\n      this.rafId = requestAnimationFrame(() => {\n        this.notifySubscribers();\n        this.rafId = null;\n      });\n    }\n  }\n\n  private notifySubscribers(): void {\n    // Don't notify if we don't have a position yet\n    if (!this.currentPosition) return;\n    \n    const currentTime = Date.now();\n    \n    this.subscribers.forEach((subscriberState) => {\n      const { subscription, lastCallTime, timeoutId } = subscriberState;\n      const { throttleMs = 0 } = subscription;\n\n      // Apply throttling if specified\n      if (throttleMs > 0) {\n        const timeSinceLastCall = currentTime - lastCallTime;\n        \n        if (timeSinceLastCall >= throttleMs) {\n          // Call immediately\n          this.callSubscriber(subscriberState);\n        } else {\n          // Schedule delayed call\n          if (timeoutId) {\n            clearTimeout(timeoutId);\n          }\n          \n          subscriberState.timeoutId = setTimeout(() => {\n            this.callSubscriber(subscriberState);\n            subscriberState.timeoutId = null;\n          }, throttleMs - timeSinceLastCall);\n        }\n      } else {\n        // No throttling, call immediately\n        this.callSubscriber(subscriberState);\n      }\n    });\n  }\n\n  private callSubscriber(subscriberState: SubscriberState): void {\n    if (!this.currentPosition) return;\n    \n    subscriberState.subscription.callback(this.currentPosition);\n    subscriberState.lastCallTime = Date.now();\n  }\n\n\n\n  private loadGlobalPosition(): void {\n    // Try to load position from global storage for persistence across navigation\n    try {\n      const stored = (window as any).__mouseTrackerPosition__;\n      if (stored && typeof stored.x === 'number' && typeof stored.y === 'number') {\n        this.currentPosition = stored;\n      }\n    } catch {\n      // Ignore errors when accessing global position\n    }\n  }\n\n  private saveGlobalPosition(): void {\n    // Save current position globally for persistence\n    if (this.currentPosition) {\n      try {\n        (window as any).__mouseTrackerPosition__ = { ...this.currentPosition };\n      } catch {\n        // Ignore errors when saving global position\n      }\n    }\n  }\n\n  // Public method to get current position (useful for initial positioning)\n  getCurrentPosition(): { x: number; y: number } | null {\n    return this.currentPosition ? { ...this.currentPosition } : null;\n  }\n\n  // For testing/debugging\n  getSubscriberCount(): number {\n    return this.subscribers.size;\n  }\n\n  // Cleanup method for testing\n  static resetInstance(): void {\n    if (MouseTracker.instance) {\n      MouseTracker.instance.stopListening();\n      MouseTracker.instance = null;\n    }\n  }\n}\n\nexport { MouseTracker }; ","import { isSSR } from './ssr';\nimport { MouseTracker } from './MouseTracker';\n\nexport interface CursorSubscription {\n  id: string;\n  onPositionChange: (position: { x: number; y: number }) => void;\n  throttleMs?: number;\n}\n\ninterface CoordinatorSubscriberState {\n  subscription: CursorSubscription;\n  lastCallTime: number;\n  timeoutId: NodeJS.Timeout | null;\n}\n\nclass CursorCoordinator {\n  private static instance: CursorCoordinator | null = null;\n  private subscribers = new Map<string, CoordinatorSubscriberState>();\n  private mouseTracker: MouseTracker;\n  private currentGlobalPosition: { x: number; y: number } | null = null;\n  private isListening = false;\n  private rafId: number | null = null;\n\n  private constructor() {\n    this.mouseTracker = MouseTracker.getInstance();\n    this.handleLayoutChange = this.handleLayoutChange.bind(this);\n  }\n\n  static getInstance(): CursorCoordinator {\n    if (!CursorCoordinator.instance) {\n      CursorCoordinator.instance = new CursorCoordinator();\n    }\n    return CursorCoordinator.instance;\n  }\n\n  subscribe(subscription: CursorSubscription): () => void {\n    if (isSSR()) {\n      // eslint-disable-next-line @typescript-eslint/no-empty-function\n      return () => {};\n    }\n\n    const subscriberState: CoordinatorSubscriberState = {\n      subscription,\n      lastCallTime: 0,\n      timeoutId: null,\n    };\n\n    this.subscribers.set(subscription.id, subscriberState);\n    \n    // Start listening if this is the first subscriber\n    if (!this.isListening) {\n      this.startListening();\n    }\n\n    // Subscribe to mouse tracker for position updates\n    const mouseUnsubscribe = this.mouseTracker.subscribe({\n      id: `coordinator-${subscription.id}`,\n      callback: (position) => {\n        this.updateGlobalPosition(position);\n        this.notifyPositionChange(subscription.id, position);\n      },\n      throttleMs: subscription.throttleMs,\n    });\n\n    // Return combined unsubscribe function\n    return () => {\n      mouseUnsubscribe();\n      this.unsubscribe(subscription.id);\n    };\n  }\n\n  private unsubscribe(id: string): void {\n    const subscriberState = this.subscribers.get(id);\n    if (subscriberState?.timeoutId) {\n      clearTimeout(subscriberState.timeoutId);\n    }\n    \n    this.subscribers.delete(id);\n    \n    // Stop listening if no more subscribers\n    if (this.subscribers.size === 0) {\n      this.stopListening();\n    }\n  }\n\n  private startListening(): void {\n    if (this.isListening || isSSR()) return;\n    \n    // Listen for layout-changing events\n    document.addEventListener('scroll', this.handleLayoutChange, true);\n    window.addEventListener('resize', this.handleLayoutChange);\n    this.isListening = true;\n  }\n\n  private stopListening(): void {\n    if (!this.isListening) return;\n    \n    document.removeEventListener('scroll', this.handleLayoutChange, true);\n    window.removeEventListener('resize', this.handleLayoutChange);\n    this.isListening = false;\n    \n    if (this.rafId) {\n      cancelAnimationFrame(this.rafId);\n      this.rafId = null;\n    }\n  }\n\n  private handleLayoutChange(): void {\n    // Batch layout change notifications using RAF\n    if (this.rafId === null) {\n      this.rafId = requestAnimationFrame(() => {\n        this.notifyAllSubscribersWithCurrentPosition();\n        this.rafId = null;\n      });\n    }\n  }\n\n  private updateGlobalPosition(position: { x: number; y: number }): void {\n    this.currentGlobalPosition = position;\n  }\n\n  private notifyPositionChange(subscriptionId: string, position: { x: number; y: number }): void {\n    const subscriberState = this.subscribers.get(subscriptionId);\n    if (!subscriberState) return;\n\n    subscriberState.subscription.onPositionChange(position);\n  }\n\n  private notifyAllSubscribersWithCurrentPosition(): void {\n    if (!this.currentGlobalPosition) return;\n    \n    this.subscribers.forEach((subscriberState) => {\n      subscriberState.subscription.onPositionChange(this.currentGlobalPosition!);\n    });\n  }\n\n  getSubscriberCount(): number {\n    return this.subscribers.size;\n  }\n\n  // Cleanup method for testing\n  static resetInstance(): void {\n    if (CursorCoordinator.instance) {\n      CursorCoordinator.instance.stopListening();\n      CursorCoordinator.instance = null;\n    }\n  }\n}\n\nexport { CursorCoordinator }; "]}