import { TransitionStartFunction } from "react";
import { StandardSchemaV1 } from "@standard-schema/spec";

//#region src/defs.d.ts
type SearchParams = Record<string, string | string[] | undefined>;
type HistoryOptions = "replace" | "push";
type LimitUrlUpdates = {
  method: "debounce";
  timeMs: number;
} | {
  method: "throttle";
  timeMs: number;
};
type Options = {
  /**
  * How the query update affects page history
  *
  * `push` will create a new history entry, allowing to use the back/forward
  * buttons to navigate state updates.
  * `replace` (default) will keep the current history point and only replace
  * the query string.
  */
  history?: HistoryOptions;
  /**
  * Scroll to top after a query state update
  *
  * Defaults to `false`, unlike the Next.js router page navigation methods.
  */
  scroll?: boolean;
  /**
  * Shallow mode (true by default) keeps query states update client-side only,
  * meaning there won't be calls to the server.
  *
  * Setting it to `false` will trigger a network request to the server with
  * the updated querystring.
  */
  shallow?: boolean;
  /**
  * Maximum amount of time (ms) to wait between updates of the URL query string.
  *
  * This is to alleviate rate-limiting of the Web History API in browsers,
  * and defaults to 50ms. Safari requires a higher value of around 120ms.
  *
  * Note: the value will be limited to a minimum of 50ms, anything lower
  * will not have any effect.
  *
  * @deprecated use `limitUrlUpdates: { 'method': 'throttle', timeMs: number }`
  * or use the shorthand:
  * ```ts
  * import { throttle } from 'nuqs'
  *
  * limitUrlUpdates: throttle(100) // time in ms
  * ```
  */
  throttleMs?: number;
  /**
  * Limit the rate of URL updates to prevent spamming the browser history,
  * and the server if `shallow: false`.
  *
  * This is to alleviate rate-limiting of the Web History API in browsers,
  * and defaults to 50ms. Safari requires a higher value of around 120ms.
  *
  * Note: the value will be limited to a minimum of 50ms, anything lower
  * will not have any effect.
  *
  * If both `throttleMs` and `limitUrlUpdates` are set, `limitUrlUpdates` will
  * take precedence.
  */
  limitUrlUpdates?: LimitUrlUpdates;
  /**
  * In RSC frameworks, opt-in to observing Server Component loading states when
  * doing non-shallow updates by passing a `startTransition` from the
  * `React.useTransition()` hook.
  *
  * In other frameworks, navigation events triggered by a query update can also
  * be wrapped in a transition this way (e.g. `React.startTransition`).
  */
  startTransition?: TransitionStartFunction;
  /**
  * Clear the key-value pair from the URL query string when setting the state
  * to the default value.
  *
  * Defaults to `true` to keep URLs clean.
  *
  * Set it to `false` to keep backwards-compatiblity when the default value
  * changes (prefer explicit URLs whose meaning don't change).
  */
  clearOnDefault?: boolean;
};
type Nullable<T> = { [K in keyof T]: T[K] | null } & {};
/**
* Helper type to define and reuse urlKey options to rename search params keys
*
* Usage:
* ```ts
* import { type UrlKeys } from 'nuqs' // or 'nuqs/server'
*
* export const coordinatesSearchParams = {
*   latitude: parseAsFloat.withDefault(0),
*   longitude: parseAsFloat.withDefault(0),
* }
* export const coordinatesUrlKeys: UrlKeys<typeof coordinatesSearchParams> = {
*   latitude: 'lat',
*   longitude: 'lng',
* }
*
* // Later in the code:
* useQueryStates(coordinatesSearchParams, {
*   urlKeys: coordinatesUrlKeys
* })
* createSerializer(coordinatesSearchParams, {
*   urlKeys: coordinatesUrlKeys
* })
* createSearchParamsCache(coordinatesSearchParams, {
*   urlKeys: coordinatesUrlKeys
* })
* ```
*/
type UrlKeys<Parsers extends Record<string, any>> = Partial<Record<keyof Parsers, string>>;
//#endregion
//#region src/parsers.d.ts
type Require<T, Keys extends keyof T> = Pick<Required<T>, Keys> & Omit<T, Keys>;
type Parser<T> = {
  /**
  * Convert a query string value into a state value.
  *
  * If the string value does not represent a valid state value,
  * the parser should return `null`. Throwing an error is also supported.
  */
  parse: (value: string) => T | null;
  /**
  * Render the state value into a query string value.
  */
  serialize?: (value: T) => string;
  /**
  * Check if two state values are equal.
  *
  * This is used when using the `clearOnDefault` value, to compare the default
  * value with the set value.
  *
  * It makes sense to provide this function when the state value is an object
  * or an array, as the default referential equality check will not work.
  */
  eq?: (a: T, b: T) => boolean;
};
type ParserBuilder<T> = Required<Parser<T>> & Options & {
  /**
  * Set history type, shallow routing and scroll restoration options
  * at the hook declaration level.
  *
  * Note that you can override those options in individual calls to the
  * state updater function.
  */
  withOptions<This>(this: This, options: Options): This;
  /**
  * Specifying a default value makes the hook state non-nullable when the
  * query is missing from the URL: the default value is returned instead
  * of `null`.
  *
  * Setting the state to the default value¹ will clear the query string key
  * from the URL, unless `clearOnDefault` is set to `false`.
  *
  * Setting the state to `null` will always clear the query string key
  * from the URL, and return the default value.
  *
  * ¹: Equality is checked with the parser's `eq` function, or referential
  * equality if not provided.
  *
  * @param defaultValue
  */
  withDefault(this: ParserBuilder<T>, defaultValue: NonNullable<T>): Omit<ParserBuilder<T>, "parseServerSide"> & {
    readonly defaultValue: NonNullable<T>;
    /**
    * Use the parser in Server Components
    *
    * `parse` is intended to be used only by the hook, but you can use this
    * method to hydrate query values on server-side rendered pages.
    * See the `server-side-parsing` demo for an example.
    *
    * Note that when multiple queries are presented to the parser
    * (eg: `/?a=1&a=2`), only the **first** will be parsed, to mimic the
    * behaviour of URLSearchParams:
    * https://url.spec.whatwg.org/#dom-urlsearchparams-get
    *
    * @param value as coming from page props
    *
    * @deprecated prefer using loaders instead, as they enforce a strong
    * bond between the data type and the search param key.
    */
    parseServerSide(value: string | string[] | undefined): NonNullable<T>;
  };
  /**
  * Use the parser in Server Components
  *
  * `parse` is intended to be used only by the hook, but you can use this
  * method to hydrate query values on server-side rendered pages.
  * See the `server-side-parsing` demo for an example.
  *
  * Note that when multiple queries are presented to the parser
  * (eg: `/?a=1&a=2`), only the **first** will be parsed, to mimic the
  * behaviour of URLSearchParams:
  * https://url.spec.whatwg.org/#dom-urlsearchparams-get
  *
  * @param value as coming from page props
  *
  * @deprecated prefer using loaders instead, as they enforce a strong
  * bond between the data type and the search param key.
  */
  parseServerSide(value: string | string[] | undefined): T | null;
};
/**
* Wrap a set of parse/serialize functions into a builder pattern parser
* you can pass to one of the hooks, making its default value type safe.
*/
declare function createParser<T>(parser: Require<Parser<T>, "parse" | "serialize">): ParserBuilder<T>;
declare const parseAsString: ParserBuilder<string>;
declare const parseAsInteger: ParserBuilder<number>;
declare const parseAsIndex: ParserBuilder<number>;
declare const parseAsHex: ParserBuilder<number>;
declare const parseAsFloat: ParserBuilder<number>;
declare const parseAsBoolean: ParserBuilder<boolean>;
/**
* Querystring encoded as the number of milliseconds since epoch,
* and returned as a Date object.
*/
declare const parseAsTimestamp: ParserBuilder<Date>;
/**
* Querystring encoded as an ISO-8601 string (UTC),
* and returned as a Date object.
*/
declare const parseAsIsoDateTime: ParserBuilder<Date>;
/**
* Querystring encoded as an ISO-8601 string (UTC)
* without the time zone offset, and returned as
* a Date object.
*
* The Date is parsed without the time zone offset,
* making it at 00:00:00 UTC.
*/
declare const parseAsIsoDate: ParserBuilder<Date>;
/**
* String-based enums provide better type-safety for known sets of values.
* You will need to pass the parseAsStringEnum function a list of your enum values
* in order to validate the query string. Anything else will return `null`,
* or your default value if specified.
*
* Example:
* ```ts
* enum Direction {
*   up = 'UP',
*   down = 'DOWN',
*   left = 'LEFT',
*   right = 'RIGHT'
* }
*
* const [direction, setDirection] = useQueryState(
*   'direction',
*    parseAsStringEnum<Direction>(Object.values(Direction)) // pass a list of allowed values
*      .withDefault(Direction.up)
* )
* ```
*
* Note: the query string value will be the value of the enum, not its name
* (example above: `direction=UP`).
*
* @param validValues The values you want to accept
*/
declare function parseAsStringEnum<Enum extends string>(validValues: Enum[]): ParserBuilder<Enum>;
/**
* String-based literals provide better type-safety for known sets of values.
* You will need to pass the parseAsStringLiteral function a list of your string values
* in order to validate the query string. Anything else will return `null`,
* or your default value if specified.
*
* Example:
* ```ts
* const colors = ["red", "green", "blue"] as const
*
* const [color, setColor] = useQueryState(
*   'color',
*    parseAsStringLiteral(colors) // pass a readonly list of allowed values
*      .withDefault("red")
* )
* ```
*
* @param validValues The values you want to accept
*/
declare function parseAsStringLiteral<const Literal extends string>(validValues: readonly Literal[]): ParserBuilder<Literal>;
/**
* Number-based literals provide better type-safety for known sets of values.
* You will need to pass the parseAsNumberLiteral function a list of your number values
* in order to validate the query string. Anything else will return `null`,
* or your default value if specified.
*
* Example:
* ```ts
* const diceSides = [1, 2, 3, 4, 5, 6] as const
*
* const [side, setSide] = useQueryState(
*   'side',
*    parseAsNumberLiteral(diceSides) // pass a readonly list of allowed values
*      .withDefault(4)
* )
* ```
*
* @param validValues The values you want to accept
*/
declare function parseAsNumberLiteral<const Literal extends number>(validValues: readonly Literal[]): ParserBuilder<Literal>;
/**
* Encode any object shape into the querystring value as JSON.
* Note: you may want to use `useQueryStates` for finer control over
* multiple related query keys.
*
* @param runtimeParser Runtime parser (eg: Zod schema or Standard Schema) to validate after JSON.parse
*/
declare function parseAsJson<T>(validator: ((value: unknown) => T | null) | StandardSchemaV1<T>): ParserBuilder<T>;
/**
* A comma-separated list of items.
* Items are URI-encoded for safety, so they may not look nice in the URL.
*
* @param itemParser Parser for each individual item in the array
* @param separator The character to use to separate items (default ',')
*/
declare function parseAsArrayOf<ItemType>(itemParser: Parser<ItemType>, separator?: string): ParserBuilder<ItemType[]>;
type inferSingleParserType<Parser> = Parser extends ParserBuilder<infer Value> & {
  defaultValue: infer Value;
} ? Value : Parser extends ParserBuilder<infer Value> ? Value | null : never;
type inferParserRecordType<Map extends Record<string, ParserBuilder<any>>> = { [Key in keyof Map]: inferSingleParserType<Map[Key]> } & {};
/**
* Type helper to extract the underlying returned data type of a parser
* or of an object describing multiple parsers and their associated keys.
*
* Usage:
*
* ```ts
* import { type inferParserType } from 'nuqs' // or 'nuqs/server'
*
* const intNullable = parseAsInteger
* const intNonNull = parseAsInteger.withDefault(0)
*
* inferParserType<typeof intNullable> // number | null
* inferParserType<typeof intNonNull> // number
*
* const parsers = {
*  a: parseAsInteger,
*  b: parseAsBoolean.withDefault(false)
* }
*
* inferParserType<typeof parsers>
* // { a: number | null, b: boolean }
* ```
*/
type inferParserType<Input> = Input extends ParserBuilder<any> ? inferSingleParserType<Input> : Input extends Record<string, ParserBuilder<any>> ? inferParserRecordType<Input> : never;
type ParserWithOptionalDefault<T> = ParserBuilder<T> & {
  defaultValue?: T;
};
type ParserMap = Record<string, ParserWithOptionalDefault<any>>;
//#endregion
export { HistoryOptions, LimitUrlUpdates, Nullable, Options, Parser, ParserBuilder, ParserMap, ParserWithOptionalDefault, SearchParams, UrlKeys, createParser, inferParserType, parseAsArrayOf, parseAsBoolean, parseAsFloat, parseAsHex, parseAsIndex, parseAsInteger, parseAsIsoDate, parseAsIsoDateTime, parseAsJson, parseAsNumberLiteral, parseAsString, parseAsStringEnum, parseAsStringLiteral, parseAsTimestamp };
//# sourceMappingURL=parsers-gDSkX8OH.d.ts.map