### Run Development Server
Source: https://github.com/letstri/seitu/blob/main/docs/README.md
Commands to start the development server using different package managers.
```bash
npm run dev
```
```bash
pnpm dev
```
```bash
yarn dev
```
--------------------------------
### Quick Start with Seitu React Hooks and Web Storage
Source: https://github.com/letstri/seitu/blob/main/README.md
Demonstrates how to use Seitu's `createWebStorageValue` for session storage and `useSubscription` hook in a React component. Ensure Zod is installed for schema validation.
```tsx
import { useSubscription } from 'seitu/react'
import { createWebStorageValue } from 'seitu/web'
import * as z from 'zod'
const value = createWebStorageValue({
type: 'sessionStorage',
key: 'test',
defaultValue: 0,
schema: z.number(),
})
value.get() // 0
value.set(1)
value.remove()
value.subscribe(v => console.log(v))
function Counter() {
const count = useSubscription(value)
return (
{count}
)
}
```
--------------------------------
### Basic useSubscription with localStorage
Source: https://github.com/letstri/seitu/blob/main/skills/useSubscription-vue/SKILL.md
Demonstrates basic usage of `useSubscription` with a `localStorage` value. Ensure `seitu/web` and `seitu/vue` are installed and imported.
```vue
{{ value }}
```
--------------------------------
### Create and Use a Schema Store
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/core/schema-store.mdx
Demonstrates how to create a schema store with Zod validation and default values. Shows basic get, set, and subscribe operations.
```typescript
import { createSchemaStore } from 'seitu'
import * as z from 'zod'
const store = createSchemaStore({
schema: z.object({ count: z.number(), name: z.string() }),
defaultValue: { count: 0, name: '' },
})
store.get()
store.set({ count: 1, name: 'alice' })
store.subscribe(console.log)
```
--------------------------------
### Create and Subscribe to Media Query (Vanilla JS)
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/media-query.mdx
Creates a media query handle and demonstrates its subscription and retrieval of the current state in vanilla JavaScript. Ensure `seitu/web` and `seitu/react` are installed.
```typescript
import { createMediaQuery } from 'seitu/web'
import { useSubscription } from 'seitu/react'
const isDesktop = createMediaQuery({ query: '(min-width: 768px)' })
// Usage with subscribe
isDesktop.subscribe(matches => {
console.log(matches)
})
const state = isDesktop.get()
console.log(state)
```
--------------------------------
### React useSubscription Hook Examples
Source: https://github.com/letstri/seitu/blob/main/skills/seitu-overview/SKILL.md
Demonstrates the flexibility of the `useSubscription` hook in React, showing how to subscribe to different types of Seitu primitives, including instances, factories, and storage with selectors.
```tsx
// React — instance or factory
const value = useSubscription(store)
const scroll = useSubscription(() => createScrollState({ element: () => ref.current }))
const count = useSubscription(storage, { selector: v => v.count })
```
--------------------------------
### Vue useSubscription Composable Examples
Source: https://github.com/letstri/seitu/blob/main/skills/seitu-overview/SKILL.md
Illustrates the usage of the `useSubscription` composable in Vue, showing how to subscribe to various Seitu primitives, including instances, refs, and computed properties.
```vue
// Vue — instance, ref, or getter
const value = useSubscription(store)
const data = useSubscription(computed(() => createWebStorageValue({ ... })))
```
--------------------------------
### createMediaQuery()
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/media-query.mdx
Creates a handle for a media query, allowing you to subscribe to its state changes or get its current state.
```APIDOC
## createMediaQuery()
### Description
Creates a handle for a media query. This function allows you to define a media query and then interact with its current state or subscribe to its changes.
### Parameters
#### Request Body
- **query** (string) - Required - The media query string to evaluate (e.g., '(min-width: 768px)').
### Usage
This function returns an object with `subscribe` and `get` methods.
- **`subscribe(callback)`**: Registers a callback function to be executed whenever the media query's match state changes.
- **`get()`**: Returns the current boolean state of the media query.
### Examples
#### Vanilla JavaScript
```ts
import { createMediaQuery } from 'seitu/web'
const isDesktop = createMediaQuery({ query: '(min-width: 768px)' })
isDesktop.subscribe(matches => {
console.log(matches)
})
const state = isDesktop.get()
console.log(state)
```
#### React
```tsx
import { createMediaQuery } from 'seitu/web'
import { useSubscription } from 'seitu/react'
const isDesktop = createMediaQuery({ query: '(min-width: 768px)' })
function Layout() {
const matches = useSubscription(isDesktop)
return matches ? 'i am desktop' : 'i am mobile'
}
```
```
--------------------------------
### Create and Use Reactive Web Storage
Source: https://github.com/letstri/seitu/blob/main/skills/createWebStorage/SKILL.md
Initialize a reactive web storage instance with schema validation and default values. Use the returned handle to get, set, clear, and subscribe to storage changes.
```typescript
import { createWebStorage } from 'seitu/web'
import * as z from 'zod'
const storage = createWebStorage({
type: 'localStorage',
schemas: {
token: z.string().nullable(),
preferences: z.object({ theme: z.enum(['light', 'dark']) }),
},
defaultValues: { token: null, preferences: { theme: 'light' } },
})
storage.get() // { token: null, preferences: { theme: 'light' } }
storage.set({ token: 'abc' }) // partial update
storage.clear() // remove all managed keys
storage.subscribe(console.log)
```
--------------------------------
### Media Query Creation Errors
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/media-query.mdx
Illustrates common errors when creating media queries with incomplete or malformed query strings. These examples are intended to show type-checking failures.
```tsx
import { createMediaQuery } from 'seitu/web'
import { useSubscription } from 'seitu/react'
// @errors: 2362 2322 1109
createMediaQuery({ query: '(min-width: ' })
// @errors: 2362 2322 2820
createMediaQuery({ query: '(min-width: 768' })
```
--------------------------------
### createReadableSubscription
Source: https://github.com/letstri/seitu/blob/main/skills/createReadableSubscription/SKILL.md
Composes a get function with a subscribe/notify pair into a Readable and Subscribable object. This is used internally by all Seitu primitives.
```APIDOC
## Function: createReadableSubscription
### Description
Composes a `get` function with a `subscribe`/`notify` pair into a `Readable & Subscribable` object. Use when building custom primitives that need the standard Seitu interface.
### Signature
```ts
function createReadableSubscription(
get: () => T,
subscribe: (callback: () => any, options?: SubscribeOptions) => () => void,
notify: () => void,
): Readable & Subscribable
```
### Parameters
- **get** - A function that returns the current value of type `T`.
- **subscribe** - A function that accepts a callback and optional options, and returns an unsubscribe function.
- **notify** - A function to trigger notifications.
### Returns
An object with the following properties:
- `get()`: Returns the current value.
- `subscribe(cb, opts?)`: Subscribes a callback function. The callback receives the result of `get()`.
- `~.notify`: An internal reference to the notify function.
- `~.output`: A type-level output marker.
```
--------------------------------
### Create and Use Media Query in React Component
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/media-query.mdx
Creates a media query handle and shows how to use it within a React functional component using `useSubscription`. Ensure `seitu/web` and `seitu/react` are installed.
```tsx
import { createMediaQuery } from 'seitu/web'
import { useSubscription } from 'seitu/react'
const isDesktop = createMediaQuery({ query: '(min-width: 768px)' })
// Usage with some function component
function Layout() {
const matches = useSubscription(isDesktop)
return matches ? 'i am desktop' : 'i am mobile'
}
```
--------------------------------
### Create and Use IndexedDB Storage
Source: https://github.com/letstri/seitu/blob/main/skills/createIndexedDbStorage/SKILL.md
Demonstrates creating an IndexedDB storage instance with schema validation and default values, then performing basic operations like get, set, and clear. Use this for persisting state to IndexedDB.
```typescript
import { createIndexedDbStorage } from 'seitu/web'
import * as z from 'zod'
const db = createIndexedDbStorage({
databaseName: 'app',
schemas: {
token: z.string().nullable(),
settings: z.object({ theme: z.enum(['light', 'dark']) }),
},
defaultValues: { token: null, settings: { theme: 'light' } },
})
db.get() // returns cached (defaults until hydrated)
await db.ready // wait for IndexedDB hydration
await db.set({ token: 'abc' }) // persists async
await db.clear() // resets to defaults + removes from IDB
```
--------------------------------
### createSubscription
Source: https://github.com/letstri/seitu/blob/main/skills/createSubscription/SKILL.md
Creates a subscription primitive with subscribe and notify functions. It allows for setup logic on the first subscription and cleanup when the last subscriber leaves. The subscribe function can optionally trigger the callback immediately.
```APIDOC
## createSubscription
### Description
This function is a low-level building block for creating custom reactive primitives in Seitu. It returns a pair of `subscribe` and `notify` functions, enabling custom subscribe/notify mechanics. It is used internally by all Seitu primitives.
### Signature
```ts
function createSubscription(options?: {
onFirstSubscribe?: () => (void | (() => void))
}): {
subscribe: (callback: () => any, options?: SubscribeOptions) => () => void
notify: () => void
}
```
### Behavior
- The `onFirstSubscribe` function is invoked when the first subscriber is added. It can optionally return a cleanup function that will be executed when the last subscriber is removed.
- The `subscribe` function accepts an optional `options` object. If `{ immediate: true }` is provided, the callback will be executed immediately upon subscription.
- The subscription is lazy, meaning the setup logic in `onFirstSubscribe` is only executed when the first subscriber is added.
### Parameters
#### `options` (object) - Optional
- **`onFirstSubscribe`** (function) - Optional - A function that is called when the first subscriber is added. It can return a cleanup function.
#### `subscribe` (function)
- **`callback`** (function) - Required - The function to be called when a notification occurs.
- **`options`** (object) - Optional - Options for subscription, such as `{ immediate: true }` to trigger the callback immediately.
- **`immediate`** (boolean) - Optional - If true, the callback is executed immediately upon subscription.
#### `notify` (function)
- No parameters.
### Return Value
An object containing:
- **`subscribe`**: A function to subscribe to notifications.
- **`notify`**: A function to manually trigger notifications.
```
--------------------------------
### Create a Readable Subscription
Source: https://github.com/letstri/seitu/blob/main/skills/createReadableSubscription/SKILL.md
Use this snippet to create a readable subscription by composing a get function with subscribe and notify functions. This is useful for building custom primitives that need the standard Seitu interface.
```typescript
import { createReadableSubscription, createSubscription } from 'seitu'
const { subscribe, notify } = createSubscription()
let value = 0
const get = () => value
const readable = createReadableSubscription(get, subscribe, notify)
readable.get() // 0
readable.subscribe(v => console.log(v))
```
--------------------------------
### Inline Creation of Subscription with Factory Function
Source: https://github.com/letstri/seitu/blob/main/skills/useSubscription-react/SKILL.md
This example demonstrates creating a subscription directly within the component using a factory function. It's useful for subscriptions that depend on component-specific logic or elements, like tracking scroll state.
```tsx
'use client'
import { useSubscription } from 'seitu/react'
import { createScrollState } from 'seitu/web'
import { useRef } from 'react'
function ScrollTracker() {
const ref = useRef(null)
const state = useSubscription(() =>
createScrollState({ element: () => ref.current, direction: 'vertical' })
)
return
{state.top.reached ? 'at top' : 'scrolled'}
}
```
--------------------------------
### Create a Schema-Validated Store with Zod
Source: https://github.com/letstri/seitu/blob/main/skills/createSchemaStore/SKILL.md
Use `createSchemaStore` to initialize a reactive store with a Zod schema. Provides a fallback `defaultValue` when validation fails. Includes methods for getting, setting, and subscribing to store changes.
```typescript
import { createSchemaStore } from 'seitu'
import * as z from 'zod'
const store = createSchemaStore({
schema: z.object({ count: z.number(), name: z.string() }),
defaultValue: { count: 0, name: '' },
})
store.get() // { count: 0, name: '' }
store.set({ count: 1, name: 'alice' })
store.subscribe(console.log)
```
--------------------------------
### Subscription with Selector using useSubscription
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/react/hooks.mdx
Optimize re-renders by using a selector function with `useSubscription`. This example subscribes to the 'count' property of a session storage instance, ensuring the component only re-renders when 'count' changes.
```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() {
// Usage with selector, re-renders only when count changes
const count = useSubscription(sessionStorage, { selector: value => value.count })
return
{count}
}
```
--------------------------------
### Create Typed Web Storage Value
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/index.mdx
Demonstrates creating a reactive and typed value for web storage (localStorage or sessionStorage). It includes default values and schema validation using Zod. You can get, set, and subscribe to changes in the storage value.
```typescript
import { createWebStorageValue } from 'seitu/web'
import * as z from 'zod'
const count = createWebStorageValue({
type: 'localStorage',
key: 'count',
defaultValue: 0,
schema: z.number(),
})
count.get() // 0
count.set(1)
count.set(v => v + 1)
count.subscribe(v => console.log(v))
```
--------------------------------
### Create Standalone WebStorage Value with Schema
Source: https://github.com/letstri/seitu/blob/main/skills/createWebStorageValue/SKILL.md
Use this snippet to create a reactive handle for localStorage with schema validation and a default value. It allows getting, setting, and clearing the stored value.
```typescript
import { createWebStorageValue } from 'seitu/web'
import * as z from 'zod'
const count = createWebStorageValue({
type: 'localStorage',
key: 'count',
schema: z.number(),
defaultValue: 0,
})
count.get() // 0
count.set(1)
count.set(v => v + 1)
count.clear()
```
--------------------------------
### Scroll State Subscription with useSubscription and Ref
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/react/hooks.mdx
Use `useSubscription` with a `ref` to subscribe to the scroll state of a DOM element. This example demonstrates subscribing to the 'top reached' state of a vertical scrollable div.
```tsx
'use client'
import * as React from 'react'
import { createScrollState } from 'seitu/web'
import { useSubscription } from 'seitu/react'
export default function Page() {
const ref = React.useRef(null)
const state = useSubscription(() => createScrollState({ element: () => ref.current, direction: 'vertical' }))
return (
{String(state.top.reached)}
)
}
```
--------------------------------
### Debounce Function with Reactive Return Value
Source: https://github.com/letstri/seitu/blob/main/skills/createDebouncedFn/SKILL.md
Example of using createDebouncedFn to debounce a fetch request. The debounced function also provides a reactive and subscribable return value. Use this when you need debounced execution and want to react to the function's results.
```typescript
import { createDebouncedFn } from 'seitu'
const search = createDebouncedFn((q: string) => fetch(`/api?q=${q}`), 300)
search('hello') // debounced — fires after 300ms of inactivity
search.get() // latest return value (undefined until first call)
search.subscribe(result => console.log('result:', result))
```
--------------------------------
### Create and Use a Reactive Store
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/core/store.mdx
Demonstrates creating a store with an initial state, updating it using a callback, subscribing to state changes, and retrieving the current state.
```typescript
import { createStore } from 'seitu'
const store = createStore({ count: 0 })
store.set(prev => ({ ...prev, count: prev.count + 1 }))
store.subscribe(state => console.log(state))
store.get() // { count: 0 }
```
--------------------------------
### Create and Use a Basic Store
Source: https://github.com/letstri/seitu/blob/main/skills/createStore/SKILL.md
Demonstrates the basic usage of `createStore` to initialize a store with a primitive value, retrieve its value, update it, and subscribe to changes.
```typescript
import { createStore } from 'seitu'
const count = createStore(0)
count.get() // 0
count.set(1)
count.set(prev => prev + 1)
count.subscribe(v => console.log(v))
```
--------------------------------
### Basic createSubscription Usage
Source: https://github.com/letstri/seitu/blob/main/skills/createSubscription/SKILL.md
Demonstrates how to use createSubscription to set up a subscription with event listeners. The `onFirstSubscribe` function is used to add a resize event listener, and its return value is used for cleanup when the last subscriber leaves.
```typescript
import { createSubscription } from 'seitu'
const { subscribe, notify } = createSubscription({
onFirstSubscribe() {
// setup (e.g. add event listener)
window.addEventListener('resize', notify)
return () => {
// cleanup when last subscriber leaves
window.removeEventListener('resize', notify)
}
},
})
```
--------------------------------
### Inline Subscription with useSubscription
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/react/hooks.mdx
Use `useSubscription` to subscribe to a reactive value directly within a component. This example shows subscribing to a session storage value with a default of 0.
```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
{value}
}
```
--------------------------------
### createStore
Source: https://github.com/letstri/seitu/blob/main/skills/createStore/SKILL.md
Creates a minimal reactive store with Seitu. This is useful for building reactive state with a get/set/subscribe pattern. The store can accept any value type.
```APIDOC
## createStore
### Description
Creates a minimal reactive store with Seitu. Use when building reactive state with get/set/subscribe pattern. Accepts any value type.
### Interface
```ts
interface Store extends Readable, Writable, Subscribable {}
```
### Methods
- `get()`: Returns the current value of the store.
- `set(value | updater)`: Sets the value of the store or applies an updater function. If the new value is the same reference as the previous value (`===`), notifications are skipped. For objects, it's recommended to spread to create a new reference, e.g., `store.set(prev => ({ ...prev, count: prev.count + 1 }))`.
- `subscribe(cb, opts?)`: Subscribes to changes in the store. The callback `cb` is invoked with the new value. Returns a function to unsubscribe. The `opts` parameter can include `{ immediate?: boolean }` to fire the callback immediately with the current value upon subscription.
### Example Usage
```ts
import { createStore } from 'seitu'
const count = createStore(0)
console.log(count.get()) // 0
count.set(1)
count.set(prev => prev + 1)
const unsubscribe = count.subscribe(v => console.log(v))
// To unsubscribe later:
unsubscribe()
```
```
--------------------------------
### Create Session Storage Handle (Vanilla JS)
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/web-storage.mdx
Demonstrates how to create a reactive handle for session storage with Zod schemas and default values. Use this for managing session-specific data.
```typescript
import { createWebStorage } from 'seitu/web'
import * as z from 'zod'
const sessionStorage = createWebStorage({
type: 'sessionStorage',
schemas: {
token: z.string().nullable(),
preferences: z.object({ theme: z.enum(['light', 'dark']) }),
},
defaultValues: { token: null, preferences: { theme: 'light' } },
})
sessionStorage.get() // { token: null, preferences: { theme: 'light' } }
sessionStorage.set({ token: 'abc' })
sessionStorage.get() // { token: 'abc', preferences: { theme: 'light' } }
sessionStorage.subscribe(console.log)
```
--------------------------------
### Subscription Component Usage
Source: https://github.com/letstri/seitu/blob/main/skills/Subscription-react/SKILL.md
Demonstrates how to use the Subscription component with and without a selector.
```APIDOC
## Subscription Component
### Description
A declarative render-prop component for subscribing to Seitu reactive values.
### Props
#### `value`
- **Type**: `Subscribable & Readable`
- **Description**: The reactive source to subscribe to.
#### `selector`
- **Type**: `(value) => R`
- **Description**: Optional selector function to extract specific parts of the value for granular updates.
#### `children`
- **Type**: `(value) => ReactNode`
- **Description**: A render function that receives the subscribed value and returns React nodes.
### Usage Example
```tsx
import { Subscription } from 'seitu/react'
// Basic usage
{(value) =>
{value.count}
}
// Usage with a selector
v.count}>
{(count) =>
{count}
}
```
```
--------------------------------
### Instance Subscription with useSubscription
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/react/hooks.mdx
Subscribe to a pre-created Seitu instance using `useSubscription`. This allows for managing multiple reactive values within a single instance, as shown with 'count' and 'name'.
```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
{value.count}
}
```
--------------------------------
### Create Reactive Media Queries
Source: https://github.com/letstri/seitu/blob/main/skills/createMediaQuery/SKILL.md
Use createMediaQuery to create reactive booleans for tracking CSS media query matches. Import from 'seitu/web'. The hook is lazy and only subscribes when needed.
```typescript
import { createMediaQuery } from 'seitu/web'
const isDark = createMediaQuery({ query: '(prefers-color-scheme: dark)' })
const isDesktop = createMediaQuery({ query: '(min-width: 768px)' })
isDark.get() // boolean
isDark.subscribe(matches => console.log(matches))
```
--------------------------------
### Create and Use a Debounced Readable
Source: https://github.com/letstri/seitu/blob/main/skills/createDebounced/SKILL.md
Demonstrates how to create a debounced readable from a store and subscribe to its delayed updates. Use this when you need to limit the frequency of updates from a reactive source.
```typescript
import { createStore, createDebounced } from 'seitu'
const input = createStore('')
const debounced = createDebounced(input, 300)
debounced.subscribe(value => console.log('debounced:', value))
debounced.get() // current debounced value
```
--------------------------------
### Create IndexedDB Storage (Vanilla JS)
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/indexed-db-storage.mdx
Creates a reactive handle for an IndexedDB object store. Use this for managing application settings or user preferences that need to persist across sessions and tabs.
```typescript
import { createIndexedDbStorage } from 'seitu/web'
import * as z from 'zod'
const settingsStorage = createIndexedDbStorage({
databaseName: 'app',
schemas: {
token: z.string().nullable(),
preferences: z.object({ theme: z.enum(['light', 'dark']) }),
},
defaultValues: { token: null, preferences: { theme: 'light' } },
})
settingsStorage.get() // { token: null, preferences: { theme: 'light' } }
await settingsStorage.ready // value hydrated from IndexedDB
await settingsStorage.set({ token: 'abc' })
settingsStorage.get() // { token: 'abc', preferences: { theme: 'light' } }
settingsStorage.subscribe(console.log)
```
--------------------------------
### Create Web Storage Primitive
Source: https://github.com/letstri/seitu/blob/main/skills/seitu-overview/SKILL.md
Creates a web storage primitive (localStorage or sessionStorage) with schema validation and default values. Use this for managing browser-persistent state with type safety.
```typescript
import { createWebStorage } from 'seitu/web'
import * as z from 'zod'
export const settings = createWebStorage({
type: 'localStorage',
schemas: { theme: z.enum(['light', 'dark']) },
defaultValues: { theme: 'light' },
})
```
--------------------------------
### Basic Usage of useSubscription with Module-Level Instance
Source: https://github.com/letstri/seitu/blob/main/skills/useSubscription-react/SKILL.md
Use this snippet to subscribe to a module-level Seitu store in a React component. It ensures concurrent-safe reads by utilizing `useSyncExternalStore`.
```tsx
'use client'
import { useSubscription } from 'seitu/react'
import { createStore } from 'seitu'
const count = createStore(0)
function Counter() {
const value = useSubscription(count)
return
}
```
--------------------------------
### createWebStorageValue - Derived from WebStorage
Source: https://github.com/letstri/seitu/blob/main/skills/createWebStorageValue/SKILL.md
Creates a reactive handle for a single web storage value, deriving its configuration (storage type, schema, default value) from an existing WebStorage instance. This is useful when managing multiple values within the same storage context.
```APIDOC
## createWebStorageValue (Derived from WebStorage)
### Description
Creates a reactive handle for a single web storage value by associating it with an existing `WebStorage` instance. It inherits the schema, default value, and storage type from the parent `WebStorage` instance.
### Method Signature
```ts
createWebStorageValue(options: {
storage: WebStorage;
key: string;
}): WebStorageValue
```
### Parameters
#### Options
- **`storage`** (`WebStorage`) - Required - An existing `WebStorage` instance from which to derive settings.
- **`key`** (`string`) - Required - The key for the specific value within the provided `WebStorage` instance.
### Usage Example
```ts
import { createWebStorage, createWebStorageValue } from 'seitu/web'
// Assume storage is an initialized WebStorage instance
const storage = createWebStorage({ type: 'sessionStorage', schema: z.object({ /* ... */ }) });
const token = createWebStorageValue({ storage, key: 'token' });
// token will inherit schema, default, and storage type from 'storage'
```
### Interface
`WebStorageValue` extends `Subscribable`, `Readable`, `Writable`, `Clearable`.
```
--------------------------------
### Web Storage with Prefixed Keys
Source: https://github.com/letstri/seitu/blob/main/skills/createWebStorage/SKILL.md
Configure web storage to use prefixed keys by providing a `keyTransform` function. This is useful for namespacing storage keys to avoid conflicts.
```typescript
const storage = createWebStorage({
type: 'localStorage',
schemas: { theme: z.string() },
defaultValues: { theme: 'light' },
keyTransform: key => `myapp:${String(key)}`,
})
```
--------------------------------
### Create Session Storage Handle (React)
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/web-storage.mdx
Shows how to integrate session storage with React using the `useSubscription` hook. This is useful for managing and displaying session-scoped state within React components.
```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 (
{value.count}{value.name}
)
}
```
--------------------------------
### createMediaQuery
Source: https://github.com/letstri/seitu/blob/main/skills/createMediaQuery/SKILL.md
Creates a reactive boolean for CSS media queries. Use this when tracking media query matches reactively. It provides type-safe query strings with autocomplete for known media features.
```APIDOC
## createMediaQuery
### Description
Creates a reactive boolean for CSS media queries. Use this when tracking media query matches reactively. It provides type-safe query strings with autocomplete for known media features.
### Method Signature
createMediaQuery(options: { query: string, defaultMatches?: boolean }): MediaQuery
### Parameters
#### Options
- **query** (string) - Required - The CSS media query string.
- **defaultMatches** (boolean) - Optional - SSR fallback value. Defaults to `false`.
### Interface
`MediaQuery` extends `Subscribable` and `Readable`.
### Usage Example
```ts
import { createMediaQuery } from 'seitu/web'
const isDark = createMediaQuery({ query: '(prefers-color-scheme: dark)' })
const isDesktop = createMediaQuery({ query: '(min-width: 768px)' })
isDark.get() // boolean
isDark.subscribe(matches => console.log(matches))
```
### Type-safe Queries
The `query` option supports autocomplete for standard media features like `min-width`, `max-width`, `prefers-color-scheme`, `orientation`, `hover`, `pointer`, etc., and supports `and`/`,` combinators.
```
--------------------------------
### Vanilla JavaScript - Create and Subscribe to Online Status
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/is-online.mdx
Creates a reactive signal for browser online status and subscribes to its changes. Access the current status directly using .get().
```typescript
import { createIsOnline } from 'seitu/web'
const isOnline = createIsOnline()
isOnline.subscribe(value => {
console.log(value ? 'online' : 'offline')
})
console.log(isOnline.get())
```
--------------------------------
### Create Computed with Single Source
Source: https://github.com/letstri/seitu/blob/main/skills/createComputed/SKILL.md
Use this when you need to derive a value from a single Seitu store. Ensure 'seitu' is imported.
```typescript
import { createComputed, createStore } from 'seitu'
const store = createStore({ a: 1, b: 2 })
const sum = createComputed(store, s => s.a + s.b)
sum.get() // 3
```
--------------------------------
### Create and Use Throttled Function
Source: https://github.com/letstri/seitu/blob/main/skills/createThrottledFn/SKILL.md
Demonstrates how to create a throttled function, invoke it, access its latest return value, and subscribe to its results. Use this when you need throttled function execution with a reactive return value.
```typescript
import { createThrottledFn } from 'seitu'
const log = createThrottledFn((msg: string) => console.log(msg), 300)
log('hello') // fires immediately
log('world') // throttled — fires after 300ms
log.get() // latest return value (undefined until first call)
log.subscribe(result => console.log('result:', result))
```
--------------------------------
### Create Session Storage Value with Existing Storage
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/web-storage-value.mdx
Creates a reactive handle for a specific key within an existing, pre-configured web storage instance. This is useful when you have multiple related storage items managed by a single `createWebStorage` instance.
```typescript
import { createWebStorage, createWebStorageValue } from 'seitu/web'
import * as z from 'zod'
const sessionStorage = createWebStorage({
type: 'sessionStorage',
schemas: { count: z.number(), name: z.string() },
defaultValues: { count: 0, name: '' },
})
const countStorage = createWebStorageValue({
storage: sessionStorage,
key: 'count',
})
countStorage.get() // 0
countStorage.set(1)
countStorage.get() // 1
```
--------------------------------
### Create and Use a Throttled Function
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/core/throttled-fn.mdx
Demonstrates how to create a throttled function that logs messages and subscribes to its results. The first call executes immediately, while subsequent calls within the wait period are batched and executed after the delay.
```typescript
import { createThrottledFn } from 'seitu'
const log = createThrottledFn((msg: string) => console.log(msg), 300)
log.subscribe(result => console.log('result:', result))
log('hello') // fires immediately
log('world') // throttled — fires after 300ms
log.get() // latest return value (undefined until first call)
```
--------------------------------
### createDebouncedFn Signature and Usage
Source: https://github.com/letstri/seitu/blob/main/skills/createDebouncedFn/SKILL.md
Defines the signature for `createDebouncedFn` and demonstrates its usage for debouncing function calls while maintaining a subscribable return value.
```APIDOC
## createDebouncedFn
### Description
Wraps a plain function. The return value becomes subscribable state. Each call resets the debounce timer.
### Signature
```ts
function createDebouncedFn any>(fn: F, wait: number): DebouncedFn
```
### Interface
```ts
interface DebouncedFn extends Readable | undefined>, Subscribable | undefined> {
(...args: Parameters): void
}
```
Callable + readable + subscribable. `get()` returns `undefined` until first execution.
### Example Usage
```ts
import { createDebouncedFn } from 'seitu'
const search = createDebouncedFn((q: string) => fetch(`/api?q=${q}`), 300)
search('hello') // debounced — fires after 300ms of inactivity
search.get() // latest return value (undefined until first call)
search.subscribe(result => console.log('result:', result))
```
```
--------------------------------
### createIsOnline
Source: https://github.com/letstri/seitu/blob/main/skills/createIsOnline/SKILL.md
Creates a reactive boolean that reflects the browser's online status (`navigator.onLine`). It subscribes to 'online' and 'offline' window events and provides a lazy subscription mechanism. Returns `true` during SSR.
```APIDOC
## createIsOnline
### Description
Creates a reactive boolean for `navigator.onLine` status. It listens to `online` and `offline` window events and provides a lazy subscription. Returns `true` during Server-Side Rendering (SSR) when the `navigator` object is undefined.
### Usage
```ts
import { createIsOnline } from 'seitu/web';
const online = createIsOnline();
// Get the current online status
const currentStatus = online.get(); // boolean
// Subscribe to changes in online status
online.subscribe(isOnline => {
console.log(isOnline ? 'User is online' : 'User is offline');
});
```
### Interface
```ts
interface IsOnline extends Subscribable, Readable {}
```
### Parameters
This function does not accept any options.
### Returns
An `IsOnline` interface which is both `Subscribable` and `Readable`.
### Notes
- Returns `true` during SSR.
- The subscription is lazy; events are only listened to while subscribed.
```
--------------------------------
### Create Vertical Scroll State (Vanilla JS)
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/web/scroll-state.mdx
Creates a reactive handle to track vertical scroll position. Subscribe to state changes to log scroll details like reached status and remaining distance.
```typescript
import { createScrollState } from 'seitu/web'
const scroll = createScrollState({
element: document.querySelector('.container'),
direction: 'vertical',
threshold: 10,
})
scroll.subscribe(state => {
console.log(state.top.reached)
console.log(state.top.remaining)
console.log(state.bottom.reached)
console.log(state.bottom.remaining)
})
const state = scroll.get()
console.log(state)
```
--------------------------------
### createThrottled
Source: https://github.com/letstri/seitu/blob/main/skills/createThrottled/SKILL.md
Creates a throttled readable that rate-limits updates from a source subscribable. Use when you need at-most-once-per-interval reactive updates. The first update fires immediately, and a trailing update fires after the interval.
```APIDOC
## createThrottled
### Description
Wraps a source subscribable with throttle. Emits at most once every `wait` ms. First update fires immediately, trailing update fires after interval.
### Signature
```ts
function createThrottled(source: Readable & Subscribable, wait: number): Throttled
```
### Interface
```ts
interface Throttled extends Readable, Subscribable {}
```
Read-only. Lazy subscription.
```
--------------------------------
### Use Web Storage Subscription in React
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/index.mdx
Shows how to use the web storage value reactively within a React component using the `useSubscription` hook. This allows the component to re-render when the storage value changes.
```tsx
'use client'
import { createWebStorageValue } from 'seitu/web'
import { useSubscription } from 'seitu/react'
import * as z from 'zod'
export default function Page() {
const count = useSubscription(() => createWebStorageValue({
type: 'localStorage',
key: 'count',
defaultValue: 0,
schema: z.number(),
}))
return
{count}
}
```
--------------------------------
### Create Derived WebStorage Value
Source: https://github.com/letstri/seitu/blob/main/skills/createWebStorageValue/SKILL.md
Derive a reactive handle for a specific key from an existing WebStorage instance. This inherits schema, default, and storage type from the parent.
```typescript
import { createWebStorage, createWebStorageValue } from 'seitu/web'
const storage = createWebStorage({ /* ... */ })
const token = createWebStorageValue({ storage, key: 'token' })
```
--------------------------------
### Create and Subscribe to a Throttled Readable
Source: https://github.com/letstri/seitu/blob/main/skills/createThrottled/SKILL.md
Creates a throttled readable from an input store and subscribes to its updates. The first update fires immediately, and subsequent updates are rate-limited. Use this to limit the frequency of reactive updates.
```typescript
import { createStore, createThrottled } from 'seitu'
const input = createStore('')
const throttled = createThrottled(input, 300)
throttled.subscribe(value => console.log('throttled:', value))
throttled.get() // current throttled value
```
--------------------------------
### createThrottledFn
Source: https://github.com/letstri/seitu/blob/main/skills/createThrottledFn/SKILL.md
Wraps a plain function in a throttled callable that also acts as a subscribable. Use when you need throttled function execution with a reactive return value.
```APIDOC
## createThrottledFn
### Description
Wraps a plain function. The first call fires immediately. Subsequent calls within the `wait` period are batched, and only the last call fires when the interval elapses. The returned function is also readable and subscribable, providing a reactive return value.
### Signature
```ts
function createThrottledFn any>(fn: F, wait: number): ThrottledFn
```
### Interface
```ts
interface ThrottledFn extends Readable | undefined>, Subscribable | undefined> {
(...args: Parameters): void
}
```
Callable + readable + subscribable. `get()` returns `undefined` until the first execution.
### Example Usage
```ts
import { createThrottledFn } from 'seitu'
const log = createThrottledFn((msg: string) => console.log(msg), 300)
log('hello') // fires immediately
log('world') // throttled — fires after 300ms
log.get() // latest return value (undefined until first call)
log.subscribe(result => console.log('result:', result))
```
```
--------------------------------
### Updating Object Stores
Source: https://github.com/letstri/seitu/blob/main/skills/createStore/SKILL.md
Shows how to correctly update object values in a store by spreading the previous state to ensure a new reference is created, preventing unnecessary re-renders or notifications.
```typescript
const store = createStore({ count: 0, name: '' })
store.set(prev => ({ ...prev, count: prev.count + 1 }))
```
--------------------------------
### Repairing Web Storage Value Object
Source: https://github.com/letstri/seitu/blob/main/docs/content/docs/utils/validation.mdx
Demonstrates how to use `repairValueObjectWithDefault` with `createWebStorageValue` to automatically fix broken web storage value objects. This is useful when the stored object is missing keys present in the default value object.
```typescript
import { createWebStorageValue } from 'seitu/web'
import { repairValueObjectWithDefault } from 'seitu/utils'
import * as z from 'zod'
const value = createWebStorageValue({
type: 'localStorage',
schema: z.object({ a: z.number(), b: z.string() }),
key: 'storage-key',
defaultValue: { a: 0, b: 'default' },
onValidationError: repairValueObjectWithDefault,
})
value.get() // { a: 0, b: 'default' }
window.localStorage.setItem('storage-key', JSON.stringify({ a: 1 }))
value.get() // { a: 1, b: 'default' }
```
--------------------------------
### createSchemaStore
Source: https://github.com/letstri/seitu/blob/main/skills/createSchemaStore/SKILL.md
Creates a schema-validated reactive store. It ensures that all state updates conform to a predefined schema, falling back to a default value if validation fails. This is useful for managing complex application state where data consistency is crucial.
```APIDOC
## createSchemaStore
### Description
Creates a schema-validated reactive store. Use when building state that must conform to a Standard Schema (Zod, Valibot, ArkType). Falls back to `defaultValue` when validation fails.
### Method
Not applicable (function call)
### Parameters
#### Options
- **schema** (`StandardSchemaV1`) - Required - Any Standard Schema validator.
- **defaultValue** (inferred from schema) - Required - Fallback value on validation failure.
- **onValidationError?** (`(props) => void | value`) - Optional - Handler for invalid data; can return a corrected value or undefined to use the default.
### Usage Example
```ts
import { createSchemaStore } from 'seitu'
import * as z from 'zod'
const store = createSchemaStore({
schema: z.object({ count: z.number(), name: z.string() }),
defaultValue: { count: 0, name: '' },
})
store.get() // Returns the current state
store.set({ count: 1, name: 'alice' }) // Updates the state, validating against the schema
store.subscribe(console.log) // Subscribes to state changes
```
### Interface
```ts
interface SchemaStore extends Subscribable, Readable, Writable {}
```
```
--------------------------------
### Basic Subscription Component Usage
Source: https://github.com/letstri/seitu/blob/main/skills/Subscription-react/SKILL.md
Use the Subscription component with a reactive source and a render prop to display its value. The component will re-render only when the subscribed value changes.
```tsx
import { Subscription } from 'seitu/react'
{(value) =>
{value.count}
}
```
--------------------------------
### useSubscription with Dependencies for Re-creation on Prop Change
Source: https://github.com/letstri/seitu/blob/main/skills/useSubscription-react/SKILL.md
Use the `deps` option to automatically re-create the subscription when specific dependencies, such as component props, change. This is essential for subscriptions whose underlying data source or configuration depends on dynamic values.
```tsx
function UserStorage({ userId }: { userId: string }) {
const data = useSubscription(
() => createWebStorageValue({ type: 'localStorage', key: `user:${userId}`, schema, defaultValue }),
{ deps: [userId] },
)
}
```
--------------------------------
### createWebStorageValue - Standalone with Schema
Source: https://github.com/letstri/seitu/blob/main/skills/createWebStorageValue/SKILL.md
Creates a standalone reactive handle for web storage (localStorage or sessionStorage) with schema validation and a default value. This is useful for persisting a single value with type safety.
```APIDOC
## createWebStorageValue (Standalone with Schema)
### Description
Creates a reactive handle for a single web storage value (localStorage or sessionStorage) with optional schema validation and a default value. Provides methods to get, set, update, and clear the stored value.
### Method Signature
```ts
createWebStorageValue(options: {
type: 'localStorage' | 'sessionStorage';
key: string;
schema: z.ZodSchema;
defaultValue?: V;
onValidationError?: (props: { key: string; value: unknown; error: z.ZodError }) => void | V;
}): WebStorageValue
```
### Parameters
#### Options
- **`type`** (`'localStorage' | 'sessionStorage'`) - Required - Specifies the web storage backend to use.
- **`key`** (`string`) - Required - The key under which the value will be stored in the web storage.
- **`schema`** (`StandardSchemaV1`) - Required - A validator (e.g., Zod schema) to ensure the data conforms to the expected type.
- **`defaultValue`** (inferred) - Optional - The fallback value to use if no value is found in storage or if validation fails.
- **`onValidationError`** (`(props) => void | value`) - Optional - A callback function to handle validation errors. It can either log the error or return a new value.
### Usage Example
```ts
import { createWebStorageValue } from 'seitu/web'
import * as z from 'zod'
const count = createWebStorageValue({
type: 'localStorage',
key: 'count',
schema: z.number(),
defaultValue: 0,
})
console.log(count.get()); // Example: 0
count.set(1);
count.set(v => v + 1);
count.clear();
```
### Interface
`WebStorageValue` extends `Subscribable`, `Readable`, `Writable`, `Clearable`.
```
--------------------------------
### useSubscription with reactive source
Source: https://github.com/letstri/seitu/blob/main/skills/useSubscription-vue/SKILL.md
Shows how `useSubscription` automatically re-subscribes when the source is a computed property that depends on a reactive ref. This is useful for dynamic data sources.
```vue
```