seitu
Version:
112 lines • 3.85 kB
text/typescript
import { i as Subscribable, r as ServerReadable, s as Writable, t as Clearable } from "../../index-B0IeflOl.mjs";
import { i as StandardSchemaV1, t as ValidationSchemaErrorProps } from "../../validate-C_H-c0gq.mjs";
import { t as CookieAttributes } from "../../index-Bqg2H49j.mjs";
//#region src/web/cookie-value/index.d.ts
interface CookieValue<V> extends Subscribable<V>, ServerReadable<V>, Writable<V>, Clearable {}
interface CookieValueOptions<S extends StandardSchemaV1<unknown>> {
key: string;
schema: S;
defaultValue: StandardSchemaV1.InferOutput<S>;
/** Return a repaired value, or nothing to fall back to `defaultValue`. */
onValidationError?: (props: ValidationSchemaErrorProps<StandardSchemaV1.InferOutput<S>>) => void | StandardSchemaV1.InferOutput<S>;
/**
* The request's `Cookie` header, called on every server read. Seitu cannot
* know the framework, so the app passes its own reader.
*/
getServerCookies?: () => string | null | undefined;
/**
* Written with every `set`.
* Defaults: path '/', sameSite 'lax', maxAge 400 days (the browser cap).
*/
attributes?: CookieAttributes;
}
/**
* Reactive handle for one cookie. The cookie is the storage, so the server
* and the browser read the same value: pass `getServerCookies` and SSR renders
* the visitor's choice, and hydration matches it.
*
* `set` writes `document.cookie` and is a no-op on the server; sending a
* `Set-Cookie` response header is the framework's job. Keep values small: the
* encoded `name=value` pair must stay under 4 KB (bigger writes are skipped
* with a warning) and cookies travel with every request. `HttpOnly` cookies
* are invisible to JavaScript, so they cannot be read or written here.
*
* @example Vanilla
* ```ts twoslash title="theme.ts"
* import { createCookieValue } from 'seitu/web'
* import * as z from 'zod'
*
* const theme = createCookieValue({
* key: 'theme',
* schema: z.enum(['light', 'dark']),
* defaultValue: 'light',
* })
*
* theme.get()
* theme.set('dark')
* theme.subscribe(console.log)
* theme.clear()
* ```
*
* @example TanStack Start
* ```ts title="theme.ts"
* import { createIsomorphicFn } from '@tanstack/react-start'
* import { getRequestHeader } from '@tanstack/react-start/server'
* import { createCookieValue } from 'seitu/web'
* import * as z from 'zod'
*
* export const theme = createCookieValue({
* key: 'theme',
* schema: z.enum(['light', 'dark']),
* defaultValue: 'light',
* getServerCookies: createIsomorphicFn().server(() =>
* getRequestHeader('cookie')
* ),
* })
* ```
*
* @example Next.js
* ```ts title="theme.ts"
* import { cookies } from 'next/headers'
* import { createCookieValue } from 'seitu/web'
* import * as z from 'zod'
*
* export const theme = createCookieValue({
* key: 'theme',
* schema: z.enum(['light', 'dark']),
* defaultValue: 'light',
* getServerCookies: () =>
* cookies()
* .getAll()
* .map(({ name, value }) => `${name}=${value}`)
* .join('; '),
* })
* ```
*
* @example React
* ```tsx twoslash title="page.tsx"
* 'use client'
*
* import { createCookieValue } from 'seitu/web'
* import { useSubscription } from 'seitu/react'
* import * as z from 'zod'
*
* const theme = createCookieValue({
* key: 'theme',
* schema: z.enum(['light', 'dark']),
* defaultValue: 'light',
* })
*
* export default function Page() {
* const value = useSubscription(theme)
* return (
* <button onClick={() => theme.set(value === 'dark' ? 'light' : 'dark')}>
* {value}
* </button>
* )
* }
* ```
*/
declare function createCookieValue<S extends StandardSchemaV1<unknown>>(options: CookieValueOptions<S>): CookieValue<StandardSchemaV1.InferOutput<S>>;
//#endregion
export { CookieValue, CookieValueOptions, createCookieValue };