seitu
Version:
110 lines • 3.43 kB
text/typescript
import { i as Subscribable, n as Readable } from "../../index-B0IeflOl.mjs";
import * as React from "react";
//#region src/react/hooks/index.d.ts
interface UseSubscriptionOptions<S extends Subscribable<any> & Readable<any>, R = S['~']['output']> {
selector?: (value: S['~']['output']) => R;
deps?: React.DependencyList;
isEqual?: (prev: R, next: R) => boolean;
}
/**
* Subscribe to a reactive value. Pass a handle or a factory (run once; recreated
* when `deps` change).
*
* Sources with `getServer` (every `seitu/web` handle) use it for SSR and
* hydration; others use `get()`. `getSnapshot` skips selector/equality when
* source, selector, and version are unchanged — keep `selector` stable.
* Factories run during render (twice under StrictMode); keep them cheap and
* create long-lived resources at module scope.
*
* @example Inline subscription
* ```tsx twoslash title="/app/page.tsx"
* 'use client'
*
* import { createWebStorageValue } from 'seitu/web'
* import { useSubscription } from 'seitu/react'
* import * as z from 'zod'
*
* export default function Page() {
* const value = useSubscription(() => createWebStorageValue({
* type: 'sessionStorage',
* key: 'test',
* defaultValue: 0,
* schema: z.number(),
* }))
*
* return <div>{value}</div>
* }
* ```
*
* @example Instance outside of component
* ```tsx twoslash title="/app/page.tsx"
* 'use client'
*
* import { createWebStorage } from 'seitu/web'
* import { useSubscription } from 'seitu/react'
* import * as z from 'zod'
*
* const sessionStorage = createWebStorage({
* type: 'sessionStorage',
* schemas: { count: z.number(), name: z.string() },
* defaultValues: { count: 0, name: '' },
* })
*
* export default function Page() {
* const value = useSubscription(sessionStorage)
* return <div>{value.count}</div>
* }
* ```
*
* @example Subscription with selector
* ```tsx twoslash title="/app/page.tsx"
* 'use client'
*
* import { createWebStorage } from 'seitu/web'
* import { useSubscription } from 'seitu/react'
* import * as z from 'zod'
*
* const sessionStorage = createWebStorage({
* type: 'sessionStorage',
* schemas: {
* count: z.number(),
* name: z.string(),
* },
* defaultValues: { count: 0, name: '' },
* })
*
* export default function Page() {
* // Re-renders only when count changes
* const count = useSubscription(sessionStorage, { selector: value => value.count })
*
* return <div>{count}</div>
* }
* ```
*
* @example Element from a callback ref
* ```tsx twoslash title="/app/page.tsx"
* 'use client'
*
* import * as React from 'react'
* import { createScrollState } from 'seitu/web'
* import { useSubscription } from 'seitu/react'
*
* export default function Page() {
* // A callback ref plus `deps` rebuilds on remount; `() => ref.current` binds once.
* const [el, setEl] = React.useState<HTMLDivElement | null>(null)
* const state = useSubscription(
* () => createScrollState({ element: el, direction: 'vertical' }),
* { deps: [el] }
* )
*
* return (
* <div ref={setEl}>
* {String(state.top.reached)}
* </div>
* )
* }
* ```
*/
declare function useSubscription<S extends Subscribable<any> & Readable<any>, R = S['~']['output']>(source: S | (() => S), options?: UseSubscriptionOptions<S, R>): R;
//#endregion
export { UseSubscriptionOptions, useSubscription };