Custom Adapters
Binding kvant to your own key-value interfaces in Vue.
When the built-in interfaces aren't enough (an external store, an in-memory map, a query-string dialect, a native bridge), you can write your own adapter for any key-value interface.
The adapter contract
An adapter is a composable receiving the bound keys and resolved options, and returning an interface object:
export interface KvantVueAdapterInterface<T> {
/** Unique adapter identifier, used to namespace sync channels. */
readonly key: string
/** Current raw values for the adapter's keys. */
readonly snapshot: Readonly<Ref<Record<string, T | undefined>>>
/** Writes raw values to the underlying storage. */
readonly update: KvantAdapterUpdateFn
}
type KvantVueAdapter<T, Options> = (
keys: string[],
options: Partial<Options>,
) => KvantVueAdapterInterface<T>To have a better idea of how to implement an adapter, check out the source code of the built-in adapters:
| Interface | Adapter | Source |
|---|---|---|
| Vue Router → Route Query | kvantjs/vue-router → useRouteQueryKvantAdapter | GitHub |
| Vue Router → Route Params | kvantjs/vue-router → useRouteParamsKvantAdapter | GitHub |
| Nuxt → Cookies | kvantjs/nuxt → useCookiesKvantAdapter | GitHub |
Framework-agnostic adapters
If you want to share an adapter across framework families (React, Vue), you can implement a low-level, framework-agnostic adapter:
interface KvantAdapterInterface<T> {
/** Unique adapter identifier, used to namespace sync channels. */
readonly key: string
/**
* Subscribes to snapshot changes.
* @returns An unsubscribe function.
*/
readonly subscribe: (callback: () => void) => () => void
/** Returns the current raw values for the adapter's keys. */
readonly getSnapshot: () => Record<string, T | undefined>
/**
* Returns the raw values as rendered on the server (SSR).
* Used as the server snapshot during hydration,
* the real client values are applied right after hydration.
*
* @default getSnapshot
*/
readonly getServerSnapshot?: () => Record<string, T | undefined>
/** Writes raw values to the underlying storage. */
readonly update: (values: Record<string, unknown>) => void
/**
* Register necessary effects (listeners, subscriptions, etc.)
* @returns A cleanup function to dispose of the effects.
*/
readonly effects?: () => (() => void) | void
}
type KvantAdapter<T, Options> = (
keys: string[],
options: Partial<Options>,
) => KvantAdapterInterface<T>To have a better idea of how to implement a framework-agnostic adapter, check out the source code of the built-in adapters: