import type { Injector, Token } from '@furystack/inject';
import { deserializeQueryString as defaultDeserializeQueryString, serializeToQueryString as defaultSerializeToQueryString } from '@furystack/rest';
import { ObservableValue } from '@furystack/utils';
/**
 * Overridable settings for {@link LocationService}. Bind a replacement factory
 * via {@link useCustomSearchStateSerializer} to swap the URL query-string
 * (de)serializers used by the service.
 */
export interface LocationServiceSettings {
    serialize: typeof defaultSerializeToQueryString;
    deserialize: typeof defaultDeserializeQueryString;
}
export declare const LocationServiceSettings: Token<LocationServiceSettings, 'singleton'>;
/**
 * Singleton service that tracks browser location changes (pathname, search, hash)
 * and exposes them as observable values for reactive routing and URL-driven state.
 */
export interface LocationService {
    readonly deserializeQueryString: typeof defaultDeserializeQueryString;
    readonly onLocationPathChanged: ObservableValue<string>;
    readonly onLocationHashChanged: ObservableValue<string>;
    readonly onLocationSearchChanged: ObservableValue<string>;
    readonly onDeserializedLocationSearchChanged: ObservableValue<Record<string, unknown>>;
    readonly searchParamObservables: Map<string, ObservableValue<any>>;
    /**
     * Synchronizes the observable state with the current browser location.
     * Called internally after navigation events and history state changes.
     */
    updateState(): void;
    /**
     * Navigate to a path. Use this instead of raw history.pushState for SPA routing.
     */
    navigate(path: string): void;
    /**
     * Replace the current history entry with a new path. Use this instead of raw
     * history.replaceState for SPA redirects where the intermediate URL should
     * not appear in the browser's back/forward stack.
     */
    replace(path: string): void;
    /**
     * Gets or creates an observable for a search parameter.
     */
    useSearchParam<T>(key: string, defaultValue: T): ObservableValue<T>;
}
export declare const LocationService: Token<LocationService, 'singleton'>;
/**
 * Configures custom (de)serialization for URL search state by binding
 * {@link LocationServiceSettings} on the given injector.
 *
 * Must be called **before** any consumer resolves {@link LocationService}:
 * the service patches `history.pushState` / `history.replaceState` and
 * subscribes to `popstate` / `hashchange` on construction, and those
 * listeners are only torn down when the owning injector is disposed.
 * Rebinding after the first resolution would leak the previous instance,
 * so this helper throws loudly if that happens.
 *
 * @param injector The root injector.
 * @param serialize Function to serialize state to a query string.
 * @param deserialize Function to deserialize a query string to state.
 * @throws If {@link LocationService} has already been resolved on
 *         `injector` (or any reachable ancestor).
 */
export declare const useCustomSearchStateSerializer: (injector: Injector, serialize: typeof defaultSerializeToQueryString, deserialize: typeof defaultDeserializeQueryString) => void;
//# sourceMappingURL=location-service.d.ts.map