feat: unified API - #1350
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
commit: |
Having two passes of bundling caused the .d.ts definition of the $unified Symbol to be duplicated, causing incompatible types (unified objects couldn't be used in useQueryStates). Changing the tsdown config to do a single pass of bundling solves this. Changed the type-level test to match the best practice of defining unified objects from "nuqs/server" and forwarding them to useQueryStates imported from "nuqs".
|
These updates look very promising. I hope the next version comes out soon. 👌 |
# Conflicts: # packages/nuqs/src/api.test.ts # packages/nuqs/src/index.server.ts # packages/nuqs/src/index.ts # packages/nuqs/src/useQueryStates.ts # packages/nuqs/tsdown.config.ts
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bundle size
Brotli-compressed. Limits are set in the |
Tasks
typedRoutesin Next.js &href()in RRv7TL;DR
defineSearchParamsis a new top-level function that creates a single, reusable, composable, "unified" definition of your search params. From this one definition you get the following features:useQueryStatesAll sharing the same parser definitions and options.
Motivation
Today, using nuqs across the full stack requires assembling several separate primitives:
Options like
urlKeys,clearOnDefaultetc must be repeated at every call site. This is error-prone, and hard to keep in sync. Also it requires naming multiple exported symbols (cognitive overhead).API
defineSearchParams(parsers, options?)What you get back
The returned
searchParamsobject exposes the following:.load(anything)createLoader).serialize(values)createSerializer)['~standard'].parsers.optionsdefineSearchParams.extend(parsers, options?).pick({ key: true }).$inferUsing with
useQueryStatesPass the unified object directly as the first argument:
All options from
defineSearchParams(urlKeys, history, shallow, scroll, etc.) are automatically forwarded to the hook. You can still override any option at the hook level or at the state updater call level:Server-side loader
Serializer
Standard Schema
Works with any Standard Schema compatible library:
Composition
.extend(parsers, options?)Merge additional parsers into an existing definition. Accepts either a raw parser map or another unified object:
When extending, options are merged using an "opinionated wins" strategy:
clearOnDefaultfalsehistory'push'shallowfalsescrolltrueFor
urlKeys, values are spread-merged, with the extension's keys replacing the base's in case of conflicts..pick(keys)Create a subset from an existing definition, inheriting all options:
Type Inference
inferParserTypeWorks directly on a unified object, no need to access
.parsers:$inferhelperA convenience type helper is available on the unified object:
Option Cascade (Priority Order)
When using
defineSearchParamswithuseQueryStates, options resolve in this order (highest priority first):history'replace'shallowtruescrollfalseclearOnDefaulttruestartTransitionlimitUrlUpdatesurlKeys{ ...unified, ...hook }merge (hook wins per-key)Note:
clearOnDefaultintentionally lets parser-level override hook-level, since it's a per-key semantic (a parser declaringclearOnDefault: trueshould override a blanketclearOnDefault: falseat the hook level).Migration
This is a non-breaking, additive API. Existing code using
createLoader,createSerializer,createStandardSchemaV1, anduseQueryStateswith raw parser maps continues to work unchanged.To adopt
defineSearchParams, consolidate your parser and option declarations: