vuerl 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/useQueryState.ts","../src/internal/rate-limiter.ts","../src/internal/utils.ts","../src/useQueryStates.ts","../src/parsers.ts"],"sourcesContent":["// Composables\nexport { useQueryState } from './useQueryState'\nexport { useQueryStates } from './useQueryStates'\n\n// Parsers\nexport {\n parseAsString,\n parseAsInteger,\n parseAsFloat,\n parseAsBoolean,\n parseAsStringLiteral,\n parseAsNumberLiteral,\n parseAsArrayOf,\n parseAsNativeArrayOf,\n parseAsStringEnum,\n parseAsIsoDate,\n parseAsIsoDateTime,\n parseAsJson,\n parseAsHex,\n withDefault\n} from './parsers'\n\n// Types\nexport type { Parser, QueryStateOptions, BuildableParser, UseQueryState, UseQueryStates } from './types'\n","import { onBeforeUnmount, ref, watch } from 'vue'\nimport type { Ref } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport type { Parser, QueryStateOptions, StateSetter, StateValue } from './types'\nimport { getSafeBrowserDelay } from './internal/rate-limiter'\nimport { buildQueryString, cloneValue, normalizeQueryValue } from './internal/utils'\n\n/**\n * Composable for syncing a single query parameter with component state\n * Provides bidirectional synchronization between URL and component state\n *\n * @param key - Query parameter name\n * @param parser - Parser for type conversion\n * @param options - Configuration options\n * @returns Tuple of [state, setState]\n *\n * @example\n * ```typescript\n * const [search] = useQueryState('q', parseAsString)\n * const [count] = useQueryState('count', parseAsInteger.withDefault(0))\n *\n * // State updates immediately\n * count.value = 42\n *\n * // URL updates after debounce (browser-safe)\n * // ?count=42\n * ```\n */\nexport function useQueryState<P extends Parser<any>>(\n key: string,\n parser: P,\n options: QueryStateOptions = {}\n): [state: Ref<StateValue<P>>, setState: (value: StateSetter<P>) => void] {\n const route = useRoute()\n const router = useRouter()\n\n const parserOptions = parser.options ?? {}\n\n // Configuration\n const historyMode = options.history ?? parserOptions.history ?? 'replace'\n const clearOnDefault = options.clearOnDefault ?? parserOptions.clearOnDefault ?? true\n const shallowRouting = options.shallow ?? parserOptions.shallow ?? true\n const shouldScroll = options.scroll ?? parserOptions.scroll ?? false\n\n const browserSafeDelay = getSafeBrowserDelay()\n const customDebounce = options.debounce ?? parserOptions.debounce ?? null\n const customThrottle = options.throttle ?? parserOptions.throttle ?? null\n const resolvedDebounce = customDebounce !== null\n ? Math.max(customDebounce, browserSafeDelay)\n : null\n const resolvedThrottle = resolvedDebounce === null && customThrottle !== null\n ? Math.max(customThrottle, browserSafeDelay)\n : null\n const fallbackDebounce = resolvedDebounce ?? browserSafeDelay\n\n // State\n type State = StateValue<P>\n\n const state = ref<State>(getStateFromQueryValue(route.query[key])) as Ref<State>\n let updateTimeout: ReturnType<typeof setTimeout> | null = null\n let isNavigating = false\n let lastThrottleTimestamp = 0\n\n function resolveDefaultValue(): State {\n if (parser.default !== undefined) {\n return cloneValue(parser.default) as State\n }\n return null as State\n }\n\n function normalizeValue(value: State | ReturnType<P['parse']> | null | undefined): State {\n if (value === undefined || value === null) {\n return resolveDefaultValue()\n }\n return value as State\n }\n\n function getStateFromQueryValue(rawValue: unknown): State {\n const normalized = normalizeQueryValue(rawValue)\n const parsed = parser.parse(normalized)\n return normalizeValue(parsed ?? null)\n }\n\n /**\n * Check if value equals default (for clearing)\n */\n function equalsDefault(value: State): boolean {\n if (parser.default === undefined) {\n return value === null\n }\n if (parser.eq) {\n return parser.eq(value as any, parser.default)\n }\n return value === parser.default\n }\n\n /**\n * Update URL with current state value\n * Called after debounce delay\n */\n async function updateUrl(): Promise<void> {\n updateTimeout = null\n\n // Don't update if we're in an external navigation\n if (isNavigating) {\n return\n }\n\n const serialized = parser.serialize(state.value === null ? null : (state.value as any))\n const newQuery: Record<string, string | string[] | undefined> = {}\n\n for (const [queryKey, queryValue] of Object.entries(route.query)) {\n if (queryValue === null) {\n continue\n }\n newQuery[queryKey] = queryValue as string | string[]\n }\n\n // Determine if we should remove the parameter\n if (serialized === null || (clearOnDefault && equalsDefault(state.value))) {\n delete newQuery[key]\n } else {\n newQuery[key] = serialized\n }\n\n // Check URL length\n const urlString = buildQueryString(newQuery)\n\n if (urlString.length > 2000) {\n console.warn(\n `URL length (${urlString.length}) exceeds recommended 2000 characters. ` +\n `Consider simplifying or moving state to session storage.`\n )\n }\n\n // Update router\n const navigationTarget = shallowRouting\n ? { query: newQuery }\n : { path: route.path, hash: route.hash, query: newQuery }\n\n await router[historyMode](navigationTarget)\n\n if (shouldScroll && typeof window !== 'undefined' && typeof window.scrollTo === 'function') {\n window.scrollTo({ top: 0, left: 0, behavior: 'auto' })\n }\n }\n\n /**\n * Queue a URL update with debounce\n */\n function queueUrlUpdate(): void {\n if (resolvedThrottle !== null) {\n const now = Date.now()\n const remaining = resolvedThrottle - (now - lastThrottleTimestamp)\n\n if (remaining <= 0) {\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n updateTimeout = null\n }\n lastThrottleTimestamp = now\n void updateUrl()\n return\n }\n\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n updateTimeout = setTimeout(() => {\n lastThrottleTimestamp = Date.now()\n updateTimeout = null\n void updateUrl()\n }, remaining)\n return\n }\n\n const delay = resolvedDebounce ?? fallbackDebounce\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n updateTimeout = setTimeout(() => {\n updateTimeout = null\n void updateUrl()\n }, delay)\n }\n\n /**\n * Set state and queue URL update\n */\n function setState(value: StateSetter<P>): void {\n const computedValue = typeof value === 'function'\n ? (value as (prev: State) => State)(state.value)\n : value\n const newValue = normalizeValue(computedValue as State | null | undefined)\n\n // Use custom equality if provided, otherwise use reference equality\n const hasChanged = parser.eq ? !parser.eq(newValue as any, state.value as any) : newValue !== state.value\n\n if (hasChanged) {\n state.value = newValue\n queueUrlUpdate()\n }\n }\n\n /**\n * Watch for external URL changes (back button, direct navigation)\n */\n const urlWatcher = watch(\n () => route.query[key],\n (newValue) => {\n // Mark that we're navigating to prevent URL update race condition\n isNavigating = true\n\n // Cancel any pending URL update\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n updateTimeout = null\n }\n\n // Parse and update state from new URL\n state.value = getStateFromQueryValue(newValue)\n\n // Re-enable URL updates after next tick\n setTimeout(() => {\n isNavigating = false\n }, 0)\n }\n )\n\n // Cleanup on unmount\n onBeforeUnmount(() => {\n urlWatcher()\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n })\n\n return [state, setState]\n}\n","/**\n * Browser-aware rate limiting for URL updates\n *\n * Different browsers have different performance characteristics:\n * - Safari: Limited to ~120ms between updates without crashes\n * - Chrome/Firefox/Edge: Can handle ~50ms between updates\n *\n * This detection happens once at module load and is cached\n */\n\nlet cachedDelay: number | null = null\n\n/**\n * Detects the current browser and returns the safe minimum delay\n * for URL updates to prevent browser crashes\n */\nfunction detectBrowserDelay(): number {\n if (typeof window === 'undefined') {\n // SSR environment\n return 50\n }\n\n const userAgent = navigator.userAgent.toLowerCase()\n const isSafari =\n /safari/i.test(userAgent) &&\n !/chrome/i.test(userAgent) &&\n !/chromium/i.test(userAgent) &&\n !/firefox/i.test(userAgent)\n\n return isSafari ? 120 : 50\n}\n\n/**\n * Get the safe browser delay, cached after first call\n * @returns Minimum delay in milliseconds\n */\nexport function getSafeBrowserDelay(): number {\n if (cachedDelay === null) {\n cachedDelay = detectBrowserDelay()\n }\n return cachedDelay\n}\n\n/**\n * For testing: reset the cached delay so detection runs again\n * @internal\n */\nexport function __resetCachedDelay(): void {\n cachedDelay = null\n}\n\n/**\n * For testing: override the detected delay\n * @internal\n */\nexport function __setOverrideDelay(delay: number | null): void {\n cachedDelay = delay\n}\n","import type { QueryValue } from '../types'\n\nexport function normalizeQueryValue(value: unknown): QueryValue {\n if (value === undefined || value === null) {\n return null\n }\n\n if (Array.isArray(value)) {\n return (value.filter((item): item is string => typeof item === 'string'))\n }\n\n return typeof value === 'string' ? value : null\n}\n\nexport function buildQueryString(query: Record<string, string | string[] | undefined>): string {\n const params = new URLSearchParams()\n\n for (const [key, value] of Object.entries(query)) {\n if (typeof value === 'string') {\n params.append(key, value)\n continue\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (typeof entry === 'string') {\n params.append(key, entry)\n }\n }\n }\n }\n\n return params.toString()\n}\n\nexport function cloneValue<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.slice() as unknown as T\n }\n\n if (value instanceof Date) {\n return new Date(value) as unknown as T\n }\n\n if (value && typeof value === 'object') {\n return { ...(value as Record<string, unknown>) } as T\n }\n\n return value\n}\n","import { onBeforeUnmount, reactive, watch } from 'vue'\nimport type { UnwrapRef } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport type { Parser, QueryStateOptions, StateRecord, StateRecordUpdate } from './types'\nimport { getSafeBrowserDelay } from './internal/rate-limiter'\nimport { buildQueryString, cloneValue, normalizeQueryValue } from './internal/utils'\n\n/**\n * Composable for syncing multiple related query parameters with component state\n * Provides automatic batching - multiple setState calls within the same event loop tick\n * result in a single router.push()\n *\n * @param parsers - Mapping of query parameter names to their parsers\n * @param options - Configuration options (applies to all parameters)\n * @returns Tuple of [state, setState] where state is a reactive object\n *\n * @example\n * ```typescript\n * const [filters, setFilters] = useQueryStates({\n * search: parseAsString.withDefault(''),\n * status: parseAsStringLiteral(['active', 'inactive']).withDefault('active'),\n * limit: parseAsInteger.withDefault(20)\n * })\n *\n * // Single updates\n * setFilters({ search: 'vue' })\n *\n * // Batch updates (single URL push)\n * setFilters({\n * search: 'vue',\n * status: 'active',\n * limit: 50\n * })\n *\n * // Clear all\n * setFilters(null)\n * ```\n */\nexport function useQueryStates<TParsers extends Record<string, Parser<any>>>(\n parsers: TParsers,\n options: QueryStateOptions = {}\n): [state: UnwrapRef<StateRecord<TParsers>>, setState: (values: StateRecordUpdate<TParsers> | null) => void] {\n const route = useRoute()\n const router = useRouter()\n\n const keys = Object.keys(parsers) as Array<keyof TParsers>\n\n function findParserOption<K extends keyof QueryStateOptions>(option: K): QueryStateOptions[K] | undefined {\n for (const key of keys) {\n const parserOption = parsers[key].options?.[option]\n if (parserOption !== undefined) {\n return parserOption\n }\n }\n return undefined\n }\n\n // Configuration\n const historyMode = options.history ?? findParserOption('history') ?? 'replace'\n const shallowRouting = options.shallow ?? findParserOption('shallow') ?? true\n const shouldScroll = options.scroll ?? findParserOption('scroll') ?? false\n const globalClearOnDefault = options.clearOnDefault ?? true\n\n const browserSafeDelay = getSafeBrowserDelay()\n const parserDebounce = findParserOption('debounce')\n const parserThrottle = findParserOption('throttle')\n const customDebounce = options.debounce ?? (parserDebounce ?? null)\n const customThrottle = options.throttle ?? (parserThrottle ?? null)\n const resolvedDebounce = customDebounce !== null\n ? Math.max(customDebounce, browserSafeDelay)\n : null\n const resolvedThrottle = resolvedDebounce === null && customThrottle !== null\n ? Math.max(customThrottle, browserSafeDelay)\n : null\n const fallbackDebounce = resolvedDebounce ?? browserSafeDelay\n\n // State - initialize all fields\n const state = reactive<Record<string, any>>({}) as StateRecord<TParsers>\n\n for (const key of keys) {\n state[key] = getStateFromQueryValue(key, route.query[key as string])\n }\n\n // Batching state\n let updateTimeout: ReturnType<typeof setTimeout> | null = null\n let batchMicrotaskId: ReturnType<typeof queueMicrotask> | null = null\n let isNavigating = false\n let lastThrottleTimestamp = 0\n\n function shouldClearKey(key: keyof TParsers): boolean {\n const parserOption = parsers[key].options?.clearOnDefault\n return parserOption ?? globalClearOnDefault\n }\n\n function resolveDefaultValue(key: keyof TParsers): any {\n const parser = parsers[key]\n if (parser.default !== undefined) {\n return cloneValue(parser.default)\n }\n return null\n }\n\n function normalizeValue(key: keyof TParsers, value: any): any {\n if (value === undefined || value === null) {\n return resolveDefaultValue(key)\n }\n return value\n }\n\n function getStateFromQueryValue(key: keyof TParsers, rawValue: unknown): any {\n const normalized = normalizeQueryValue(rawValue)\n const parser = parsers[key]\n const parsed = parser.parse(normalized)\n return normalizeValue(key, parsed ?? null)\n }\n\n /**\n * Check if value equals its parser's default\n */\n function equalsDefault(key: keyof TParsers, value: any): boolean {\n const parser = parsers[key]\n if (parser.default === undefined) {\n return value === null\n }\n if (parser.eq) {\n return parser.eq(value, parser.default)\n }\n return value === parser.default\n }\n\n /**\n * Update URL with current state\n * Called after debounce/throttle delay\n */\n async function updateUrl(): Promise<void> {\n updateTimeout = null\n\n // Don't update if we're in an external navigation\n if (isNavigating) {\n return\n }\n\n const newQuery: Record<string, string | string[] | undefined> = {}\n\n for (const [queryKey, queryValue] of Object.entries(route.query)) {\n if (queryValue === null) {\n continue\n }\n newQuery[queryKey] = queryValue as string | string[]\n }\n\n // Process each key\n for (const key of keys) {\n const parser = parsers[key]\n const serialized = parser.serialize(state[key] === null ? null : state[key])\n\n // Determine if we should remove the parameter\n if (serialized === null || (shouldClearKey(key) && equalsDefault(key, state[key]))) {\n delete newQuery[key as string]\n } else {\n newQuery[key as string] = serialized\n }\n }\n\n // Check URL length\n const urlString = buildQueryString(newQuery)\n\n if (urlString.length > 2000) {\n console.warn(\n `URL length (${urlString.length}) exceeds recommended 2000 characters. ` +\n `Consider simplifying or moving state to session storage.`\n )\n }\n\n // Update router\n const navigationTarget = shallowRouting\n ? { query: newQuery }\n : { path: route.path, hash: route.hash, query: newQuery }\n\n await router[historyMode](navigationTarget)\n\n if (shouldScroll && typeof window !== 'undefined' && typeof window.scrollTo === 'function') {\n window.scrollTo({ top: 0, left: 0, behavior: 'auto' })\n }\n }\n\n /**\n * Queue a URL update with debounce\n */\n function queueUrlUpdate(): void {\n if (resolvedThrottle !== null) {\n const now = Date.now()\n const remaining = resolvedThrottle - (now - lastThrottleTimestamp)\n\n if (remaining <= 0) {\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n updateTimeout = null\n }\n lastThrottleTimestamp = now\n void updateUrl()\n return\n }\n\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n updateTimeout = setTimeout(() => {\n lastThrottleTimestamp = Date.now()\n updateTimeout = null\n void updateUrl()\n }, remaining)\n return\n }\n\n const delay = resolvedDebounce ?? fallbackDebounce\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n updateTimeout = setTimeout(() => {\n updateTimeout = null\n void updateUrl()\n }, delay)\n }\n\n /**\n * Queue URL update batching for the same event loop tick\n */\n function queueBatchUrlUpdate(): void {\n // If already queued, don't queue again\n if (batchMicrotaskId !== null) {\n return\n }\n\n // Queue a microtask to batch URL updates\n batchMicrotaskId = queueMicrotask(() => {\n batchMicrotaskId = null\n queueUrlUpdate()\n })\n }\n\n /**\n * Set state for one or more parameters\n * Updates state immediately, batches URL updates\n */\n function setState(values: StateRecordUpdate<TParsers> | null): void {\n let hasChanges = false\n\n if (values === null) {\n // Clear all to defaults\n for (const key of keys) {\n const parser = parsers[key]\n const newValue = resolveDefaultValue(key)\n const hasChanged = parser.eq ? !parser.eq(newValue, state[key]) : newValue !== state[key]\n\n if (hasChanged) {\n state[key] = newValue\n hasChanges = true\n }\n }\n } else {\n // Update each provided key\n for (const key of Object.keys(values) as Array<keyof TParsers>) {\n const providedValue = values[key]\n if (providedValue === undefined) {\n continue\n }\n\n const parser = parsers[key]\n const newValue = normalizeValue(key, providedValue)\n const hasChanged = parser.eq ? !parser.eq(newValue, state[key]) : newValue !== state[key]\n\n if (hasChanged) {\n state[key] = newValue\n hasChanges = true\n }\n }\n }\n\n // Batch URL updates\n if (hasChanges) {\n queueBatchUrlUpdate()\n }\n }\n\n /**\n * Watch for external URL changes (back button, direct navigation)\n */\n const watchers = keys.map((key) => {\n return watch(\n () => route.query[key as string],\n (newValue) => {\n // Mark that we're navigating to prevent URL update race condition\n isNavigating = true\n\n // Cancel any pending URL update\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n updateTimeout = null\n }\n\n // Parse and update state from new URL\n state[key] = getStateFromQueryValue(key, newValue)\n\n // Re-enable URL updates after next tick\n setTimeout(() => {\n isNavigating = false\n }, 0)\n }\n )\n })\n\n // Cleanup on unmount\n onBeforeUnmount(() => {\n watchers.forEach((unwatch) => unwatch())\n if (updateTimeout) {\n clearTimeout(updateTimeout)\n }\n })\n\n return [state as UnwrapRef<StateRecord<TParsers>>, setState]\n}\n","import type { BuildableParser, Parser, QueryStateOptions, QueryValue } from './types'\n\nfunction getSingleValue(value: QueryValue): string | null {\n if (value === null) {\n return null\n }\n if (Array.isArray(value)) {\n return value[0] ?? null\n }\n return value\n}\n\nfunction getArrayValues(value: QueryValue): string[] {\n if (value === null) {\n return []\n }\n if (Array.isArray(value)) {\n return value.filter((item): item is string => typeof item === 'string')\n }\n return value.length === 0 ? [] : [value]\n}\n\n/**\n * Creates a parser from a base parser with optional default value and options\n */\nfunction createBuildable<T>(base: Parser<T>): BuildableParser<T> {\n const buildable: BuildableParser<T> = {\n ...base,\n withDefault<D extends T>(defaultValue: D): BuildableParser<T> & { default: D } {\n return createBuildable({\n ...base,\n default: defaultValue\n }) as BuildableParser<T> & { default: D }\n },\n withOptions(options: Partial<QueryStateOptions>): BuildableParser<T> {\n return createBuildable({\n ...base,\n options: {\n ...(base.options ?? {}),\n ...options\n }\n })\n }\n }\n return buildable\n}\n\n/**\n * Parse raw string values\n * Returns null for null/undefined input\n *\n * @example\n * ```typescript\n * const [search] = useQueryState('q', parseAsString)\n * const [search] = useQueryState('q', parseAsString.withDefault(''))\n * ```\n */\nexport const parseAsString: BuildableParser<string> = createBuildable({\n parse: (value) => getSingleValue(value),\n serialize: (value) => (value ?? null)\n})\n\n/**\n * Parse integer values\n * Returns null for non-numeric input or NaN\n *\n * @example\n * ```typescript\n * const [count] = useQueryState('count', parseAsInteger)\n * const [count] = useQueryState('count', parseAsInteger.withDefault(0))\n * ```\n */\nexport const parseAsInteger: BuildableParser<number> = createBuildable({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n const normalized = rawValue.trim()\n if (!/^-?\\d+$/.test(normalized)) {\n return null\n }\n const num = parseInt(normalized, 10)\n return Number.isNaN(num) ? null : num\n },\n serialize: (value) => {\n if (value === null || value === undefined) return null\n return String(Math.floor(value))\n }\n})\n\n/**\n * Parse floating point values\n * Returns null for non-numeric input or NaN/Infinity\n *\n * @example\n * ```typescript\n * const [price] = useQueryState('price', parseAsFloat)\n * const [price] = useQueryState('price', parseAsFloat.withDefault(0.0))\n * ```\n */\nexport const parseAsFloat: BuildableParser<number> = createBuildable({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n const normalized = rawValue.trim()\n if (!/^[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)$/.test(normalized)) {\n return null\n }\n const num = parseFloat(normalized)\n return Number.isFinite(num) ? num : null\n },\n serialize: (value) => {\n if (value === null || value === undefined) return null\n return String(value)\n }\n})\n\n/**\n * Parse boolean values\n * Accepts 'true'/'false' strings (case-insensitive)\n * Returns null for invalid input\n *\n * @example\n * ```typescript\n * const [isActive] = useQueryState('active', parseAsBoolean)\n * const [isActive] = useQueryState('active', parseAsBoolean.withDefault(false))\n * ```\n */\nexport const parseAsBoolean: BuildableParser<boolean> = createBuildable({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n const lower = rawValue.toLowerCase()\n if (lower === 'true') return true\n if (lower === 'false') return false\n return null\n },\n serialize: (value) => {\n if (value === null || value === undefined) return null\n return String(value)\n }\n})\n\n/**\n * Parse string literal (enum-like) values\n * Provides type-safe string enum handling with compile-time validation\n * Returns null for values not in the allowed set\n *\n * @example\n * ```typescript\n * const [sort] = useQueryState(\n * 'sort',\n * parseAsStringLiteral(['asc', 'desc']).withDefault('asc')\n * )\n * // Type is now Ref<'asc' | 'desc'>, not string\n * ```\n */\nexport function parseAsStringLiteral<const T extends readonly string[]>(\n values: T\n): BuildableParser<T[number]> {\n const valueSet = new Set(values)\n\n return createBuildable<T[number]>({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n return valueSet.has(rawValue) ? (rawValue as T[number]) : null\n },\n serialize: (value) => {\n if (value === null || value === undefined) return null\n return String(value)\n }\n })\n}\n\n/**\n * Parse number literal (enum-like) values\n * Provides type-safe number enum handling with compile-time validation\n * Returns null for values not in the allowed set\n *\n * @example\n * ```typescript\n * const [limit] = useQueryState(\n * 'limit',\n * parseAsNumberLiteral([10, 20, 50]).withDefault(20)\n * )\n * // Type is now Ref<10 | 20 | 50>, not number\n * ```\n */\nexport function parseAsNumberLiteral<const T extends readonly number[]>(\n values: T\n): BuildableParser<T[number]> {\n const valueSet = new Set(values)\n\n return createBuildable<T[number]>({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n const num = parseInt(rawValue, 10)\n return !isNaN(num) && valueSet.has(num) ? (num as T[number]) : null\n },\n serialize: (value) => {\n if (value === null || value === undefined) return null\n return String(Math.floor(value))\n }\n })\n}\n\n/**\n * Parse string enums into typed values\n */\nexport function parseAsStringEnum<TEnum extends Record<string, string | number>>(\n enumObject: TEnum\n): BuildableParser<TEnum[keyof TEnum]> {\n const enumValues = new Set(\n Object.values(enumObject).filter((entry): entry is TEnum[keyof TEnum] => typeof entry === 'string')\n )\n\n return createBuildable<TEnum[keyof TEnum]>({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n return enumValues.has(rawValue as TEnum[keyof TEnum]) ? (rawValue as TEnum[keyof TEnum]) : null\n },\n serialize: (value) => {\n if (value === null || value === undefined) return null\n return String(value)\n }\n })\n}\n\n/**\n * Parse comma-separated or custom-separated values into arrays\n * Each item is parsed using the provided itemParser\n * Returns null for null/undefined input\n *\n * @example\n * ```typescript\n * const [ids] = useQueryState('ids', parseAsArrayOf(parseAsInteger))\n * // ?ids=1,2,3 → [1, 2, 3]\n *\n * const [tags] = useQueryState('tags', parseAsArrayOf(parseAsString, '|'))\n * // ?tags=a|b|c → ['a', 'b', 'c']\n * ```\n */\nexport function parseAsArrayOf<T>(\n itemParser: Parser<T>,\n separator: string = ','\n): BuildableParser<T[]> {\n return createBuildable<T[]>({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return []\n return rawValue\n .split(separator)\n .map((item) => itemParser.parse(item.trim()))\n .filter((item): item is T => item !== null)\n },\n serialize: (value) => {\n if (!value || value.length === 0) return null\n const serialized = value\n .map((item) => itemParser.serialize(item))\n .flatMap((result) => {\n if (result === null) {\n return []\n }\n return Array.isArray(result) ? result : [result]\n })\n .filter((s): s is string => typeof s === 'string')\n return serialized.length > 0 ? serialized.join(separator) : null\n },\n eq: (a, b) => {\n if (!a && !b) return true\n if (!a || !b) return false\n if (a.length !== b.length) return false\n return a.every((v, i) => {\n const itemEq = itemParser.eq\n return itemEq ? itemEq(v, b[i]) : v === b[i]\n })\n },\n default: [] as unknown as T[]\n })\n}\n\n/**\n * Parse repeated query parameters (native arrays) into typed arrays\n */\nexport function parseAsNativeArrayOf<T>(itemParser: Parser<T>): BuildableParser<T[]> {\n return createBuildable<T[]>({\n parse: (value) => {\n const inputs = getArrayValues(value)\n if (inputs.length === 0) return []\n return inputs\n .map((entry) => itemParser.parse(entry))\n .filter((item): item is T => item !== null)\n },\n serialize: (value) => {\n if (!value || value.length === 0) return null\n const serialized = value\n .map((item) => itemParser.serialize(item))\n .flatMap((result) => {\n if (result === null) {\n return []\n }\n return Array.isArray(result) ? result : [result]\n })\n .filter((entry): entry is string => typeof entry === 'string')\n return serialized.length > 0 ? serialized : null\n },\n eq: (a, b) => {\n if (!a && !b) return true\n if (!a || !b) return false\n if (a.length !== b.length) return false\n return a.every((v, i) => {\n const itemEq = itemParser.eq\n return itemEq ? itemEq(v, b[i]) : v === b[i]\n })\n },\n default: [] as unknown as T[]\n })\n}\n\n/**\n * Parse ISO 8601 date strings (YYYY-MM-DD)\n * Returns null for invalid date strings\n *\n * @example\n * ```typescript\n * const [date] = useQueryState('date', parseAsIsoDate)\n * // ?date=2025-11-22 → Date(2025-11-22T00:00:00Z)\n * ```\n */\nexport const parseAsIsoDate: BuildableParser<Date> = createBuildable({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n // Match ISO date format: YYYY-MM-DD\n const dateMatch = /^(\\d{4})-(\\d{2})-(\\d{2})$/.test(rawValue)\n if (!dateMatch) return null\n const date = new Date(rawValue + 'T00:00:00Z')\n return isNaN(date.getTime()) ? null : date\n },\n serialize: (value) => {\n if (!value) return null\n // Use toISOString but extract just the date part\n const iso = value.toISOString()\n return iso.split('T')[0]\n },\n eq: (a, b) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return a.getTime() === b.getTime()\n }\n})\n\n/**\n * Parse ISO 8601 datetime strings with timezone\n * Supports formats: 2025-11-22T10:30:00Z and 2025-11-22T10:30:00+01:00\n * Returns null for invalid datetime strings\n *\n * @example\n * ```typescript\n * const [datetime] = useQueryState('created', parseAsIsoDateTime)\n * // ?created=2025-11-22T10:30:00Z → Date(2025-11-22T10:30:00Z)\n * ```\n */\nexport const parseAsIsoDateTime: BuildableParser<Date> = createBuildable({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n // Match ISO datetime with optional milliseconds and timezone: YYYY-MM-DDTHH:MM:SS(.sss)?(Z or ±HH:MM)\n const dateTimeMatch =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/.test(rawValue)\n if (!dateTimeMatch) return null\n const date = new Date(rawValue)\n return isNaN(date.getTime()) ? null : date\n },\n serialize: (value) => {\n if (!value) return null\n return value.toISOString()\n },\n eq: (a, b) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return a.getTime() === b.getTime()\n }\n})\n\n/**\n * Parse JSON values with optional Zod schema validation\n * Returns null for invalid JSON or validation failures\n *\n * @example\n * ```typescript\n * const [filters] = useQueryState('f', parseAsJson())\n * // ?f={\"status\":\"active\"} → {status: \"active\"}\n *\n * // With Zod validation:\n * const filterSchema = z.object({ status: z.enum(['active', 'inactive']) })\n * const [filters] = useQueryState('f', parseAsJson(filterSchema))\n * ```\n */\nexport function parseAsJson<T = unknown>(schema?: any): BuildableParser<T> {\n return createBuildable<T>({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n try {\n const parsed = JSON.parse(rawValue)\n // If schema provided, validate it\n if (schema) {\n const result = schema.safeParse ? schema.safeParse(parsed) : schema.parse?.(parsed)\n if (result && !result.success) return null\n return result?.data ?? parsed\n }\n return parsed\n } catch {\n return null\n }\n },\n serialize: (value) => {\n if (value === null || value === undefined) return null\n try {\n return JSON.stringify(value)\n } catch {\n return null\n }\n }\n })\n}\n\n/**\n * Parse hex color values (6 digit hex codes)\n * Accepts both with and without # prefix\n * Returns null for invalid hex values\n *\n * @example\n * ```typescript\n * const [color] = useQueryState('color', parseAsHex)\n * // ?color=ff00ff → 'ff00ff'\n * // ?color=%23ff00ff → 'ff00ff' (URL encoded #)\n * ```\n */\nexport const parseAsHex: BuildableParser<string> = createBuildable({\n parse: (value) => {\n const rawValue = getSingleValue(value)\n if (!rawValue) return null\n // Remove # if present\n const hex = rawValue.startsWith('#') ? rawValue.slice(1) : rawValue\n // Validate hex format (6 characters)\n if (!/^[0-9a-fA-F]{6}$/.test(hex)) return null\n return hex.toLowerCase()\n },\n serialize: (value) => {\n if (!value) return null\n return value\n }\n})\n\nexport function withDefault<T, D extends T>(parser: Parser<T>, defaultValue: D): BuildableParser<T> & { default: D } {\n return createBuildable({\n ...parser,\n default: defaultValue\n }) as BuildableParser<T> & { default: D }\n}\n"],"mappings":"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","names":["import_vue","import_vue_router"]}
@@ -0,0 +1,5 @@
1
+ export { useQueryState } from './useQueryState';
2
+ export { useQueryStates } from './useQueryStates';
3
+ export { parseAsString, parseAsInteger, parseAsFloat, parseAsBoolean, parseAsStringLiteral, parseAsNumberLiteral, parseAsArrayOf, parseAsNativeArrayOf, parseAsStringEnum, parseAsIsoDate, parseAsIsoDateTime, parseAsJson, parseAsHex, withDefault } from './parsers';
4
+ export type { Parser, QueryStateOptions, BuildableParser, UseQueryState, UseQueryStates } from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAGjD,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,UAAU,EACV,WAAW,EACZ,MAAM,WAAW,CAAA;AAGlB,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA"}