{"version":3,"file":"use-position-tracker.cjs","names":[],"sources":["../../src/geo/use-position-tracker.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useLatestRef } from \"@/hooks/use-latest-ref\";\nimport {\n    createPositionTracker,\n    type CreatePositionTrackerOptions,\n    type PositionTracker,\n    type TrackerStatus,\n} from \"./create-position-tracker\";\nimport type { TrackPoint } from \"./types\";\n\nexport interface UsePositionTrackerOptions extends Omit<\n    CreatePositionTrackerOptions,\n    \"onUpdate\" | \"onStatusChange\"\n> {\n    /** Start tracking automatically on mount. Default: `false`. */\n    autoStart?: boolean;\n}\n\nexport interface UsePositionTrackerResult {\n    /** Recorded trajectory (newest last). */\n    points: readonly TrackPoint[];\n    /** Most recent point, or `null` before the first fix. */\n    lastPoint: TrackPoint | null;\n    /** Total distance of the trajectory in kilometers. */\n    distanceKm: number;\n    /** Current tracker status. */\n    status: TrackerStatus;\n    /** True while `status === \"tracking\"`. */\n    isTracking: boolean;\n    /** Begin watching position. */\n    start: () => void;\n    /** Stop watching, keeping the trajectory. */\n    stop: () => void;\n    /** Stop and discard the trajectory. */\n    clear: () => void;\n}\n\n/**\n * React hook wrapping {@link createPositionTracker}. Records a live GPS\n * trajectory tied to the component lifecycle — the watch is torn down on\n * unmount. Fully browser-side; no external service.\n *\n * @example\n * const { points, distanceKm, isTracking, start, stop } = usePositionTracker({\n *   minDistanceKm: 0.01,\n * });\n * return (\n *   <>\n *     <button onClick={isTracking ? stop : start}>{isTracking ? \"Parar\" : \"Rastrear\"}</button>\n *     <TrajectoryMap points={points} />\n *     <span>{distanceKm.toFixed(2)} km</span>\n *   </>\n * );\n */\nexport function usePositionTracker(\n    options: UsePositionTrackerOptions = {},\n): UsePositionTrackerResult {\n    const { autoStart = false, onError, ...trackerOptions } = options;\n\n    const [points, setPoints] = useState<readonly TrackPoint[]>([]);\n    const [distanceKm, setDistanceKm] = useState<number>(0);\n    const [status, setStatus] = useState<TrackerStatus>(\"idle\");\n\n    const trackerRef = useRef<PositionTracker | null>(null);\n    const onErrorRef = useLatestRef(onError);\n\n    useEffect(() => {\n        const tracker = createPositionTracker({\n            ...trackerOptions,\n            onUpdate: (next) => {\n                setPoints([...next]);\n                setDistanceKm(tracker.distanceKm);\n            },\n            onStatusChange: setStatus,\n            onError: (error) => onErrorRef.current?.(error),\n        });\n        trackerRef.current = tracker;\n        if (autoStart) tracker.start();\n\n        return () => {\n            tracker.stop();\n            trackerRef.current = null;\n        };\n        // Tracker options are read once at creation; changing them mid-track\n        // would drop the recorded trajectory, so they are intentionally omitted.\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, []);\n\n    const start = useCallback((): void => trackerRef.current?.start(), []);\n    const stop = useCallback((): void => trackerRef.current?.stop(), []);\n    const clear = useCallback((): void => {\n        trackerRef.current?.clear();\n        setDistanceKm(0);\n    }, []);\n\n    return {\n        points,\n        lastPoint: points.length > 0 ? points[points.length - 1] : null,\n        distanceKm,\n        status,\n        isTracking: status === \"tracking\",\n        start,\n        stop,\n        clear,\n    };\n}\n"],"mappings":"iHAsDA,SAAgB,EACZ,EAAqC,CAAC,EACd,CACxB,GAAM,CAAE,YAAY,GAAO,UAAS,GAAG,GAAmB,EAEpD,CAAC,EAAQ,IAAA,EAAa,EAAA,SAAA,CAAgC,CAAC,CAAC,EACxD,CAAC,EAAY,IAAA,EAAiB,EAAA,SAAA,CAAiB,CAAC,EAChD,CAAC,EAAQ,IAAA,EAAa,EAAA,SAAA,CAAwB,MAAM,EAEpD,GAAA,EAAa,EAAA,OAAA,CAA+B,IAAI,EAChD,EAAa,EAAA,aAAa,CAAO,GAEvC,EAAA,EAAA,UAAA,KAAgB,CACZ,IAAM,EAAU,EAAA,sBAAsB,CAClC,GAAG,EACH,SAAW,GAAS,CAChB,EAAU,CAAC,GAAG,CAAI,CAAC,EACnB,EAAc,EAAQ,UAAU,CACpC,EACA,eAAgB,EAChB,QAAU,GAAU,EAAW,UAAU,CAAK,CAClD,CAAC,EAID,MAHA,GAAW,QAAU,EACjB,GAAW,EAAQ,MAAM,MAEhB,CACT,EAAQ,KAAK,EACb,EAAW,QAAU,IACzB,CAIJ,EAAG,CAAC,CAAC,EAEL,IAAM,GAAA,EAAQ,EAAA,YAAA,KAAwB,EAAW,SAAS,MAAM,EAAG,CAAC,CAAC,EAC/D,GAAA,EAAO,EAAA,YAAA,KAAwB,EAAW,SAAS,KAAK,EAAG,CAAC,CAAC,EAC7D,GAAA,EAAQ,EAAA,YAAA,KAAwB,CAClC,EAAW,SAAS,MAAM,EAC1B,EAAc,CAAC,CACnB,EAAG,CAAC,CAAC,EAEL,MAAO,CACH,SACA,UAAW,EAAO,OAAS,EAAI,EAAO,EAAO,OAAS,GAAK,KAC3D,aACA,SACA,WAAY,IAAW,WACvB,QACA,OACA,OACJ,CACJ"}