### Development commands Source: https://github.com/zakirkun/seblak/blob/main/README.md Common development commands for the project: install dependencies, start the dev server, build the library, run tests, and lint code. ```bash # Install dependencies npm install # Start development server npm run dev # Build library npm run build:lib # Run tests npm test # Lint code npm run lint ``` -------------------------------- ### Install @zakirkun/seblak with npm/yarn/pnpm Source: https://github.com/zakirkun/seblak/blob/main/README.md Install the @zakirkun/seblak package using npm, yarn, or pnpm. ```bash npm install @zakirkun/seblak # or yarn add @zakirkun/seblak # or pnpm add @zakirkun/seblak ``` -------------------------------- ### Basic store with createStore and useSeblak Source: https://github.com/zakirkun/seblak/blob/main/README.md Basic store example using createStore and useSeblak. Defines a CounterState interface, creates a store with initial state and optional name, and uses actions.setState and actions.reset in a React component. ```tsx import { createStore, useSeblak } from '@zakirkun/seblak' // Define your state shape interface CounterState { count: number name: string } // Create a store const counterStore = createStore({ initialState: { count: 0, name: 'My Counter' }, name: 'counter' // optional, for debugging }) // Use in your React component function Counter() { const [state, actions] = useSeblak(counterStore) const increment = () => { actions.setState({ count: state.data.count + 1 }) } return (

{state.data.name}

Count: {state.data.count}

) } ``` -------------------------------- ### Query hooks with useQuery and useMutation Source: https://github.com/zakirkun/seblak/blob/main/README.md Query hooks example using useQuery and useMutation. Fetches users with useQuery (staleTime 30s) and creates users with useMutation, refetching on success. Handles loading and error states. ```tsx import { useQuery, useMutation } from '@zakirkun/seblak' function UserList() { // Fetch data with useQuery const { data: users, isLoading, error, refetch } = useQuery({ queryKey: ['users'], queryFn: () => fetch('/api/users').then(res => res.json()), staleTime: 30000 // 30 seconds }) // Mutations for data updates const { mutate: createUser, isLoading: isCreating } = useMutation({ mutationFn: (userData) => fetch('/api/users', { method: 'POST', body: JSON.stringify(userData) }).then(res => res.json()), onSuccess: () => { refetch() // Refetch users after creating } }) const handleCreateUser = () => { createUser({ name: 'New User', email: 'user@example.com' }) } if (isLoading) return
Loading...
if (error) return
Error: {error}
return (
) } ``` -------------------------------- ### Async store with createAsyncStore and useAsyncSeblak Source: https://github.com/zakirkun/seblak/blob/main/README.md Async store example using createAsyncStore and useAsyncSeblak. Fetches user data with a fetcher, sets staleTime to 1 minute and retry to 3. The component shows loading, error, and data states, and supports refetching. ```tsx import { createAsyncStore, useAsyncSeblak } from '@zakirkun/seblak' // Create async store for API data const userStore = createAsyncStore({ fetcher: () => fetch('/api/user').then(res => res.json()), name: 'user', staleTime: 60000, // 1 minute retry: 3 }) function UserProfile() { const [state, actions] = useAsyncSeblak(userStore) return (
{state.loading &&
Loading...
} {state.error &&
Error: {state.error}
} {state.data && (

{state.data.name}

{state.data.email}

)}
) } ``` -------------------------------- ### Migration from Zustand: createStore and useSeblak Source: https://github.com/zakirkun/seblak/blob/main/README.md Migration example from Zustand to Seblak. Create a store with createStore and initialState, then use useSeblak in components to access state and actions. The addUser action uses actions.setState to update the users array. ```tsx // Zustand const useStore = create(set => ({ users: [], addUser: user => set(state => ({ users: [...state.users, user] })) })) // Seblak equivalent const userStore = createStore({ initialState: { users: [] } }) // In component const [state, actions] = useSeblak(userStore) const addUser = user => actions.setState({ users: [...state.data.users, user] }) ``` -------------------------------- ### Migration from React Query: useQuery Options Object Source: https://github.com/zakirkun/seblak/blob/main/README.md Migration example from React Query to Seblak. The Seblak useQuery hook uses an options object with queryKey and queryFn instead of positional arguments. ```tsx // React Query const { data, isLoading, error, refetch } = useQuery(['users'], fetchUsers) // Seblak equivalent const { data, isLoading, error, refetch } = useQuery({ queryKey: ['users'], queryFn: fetchUsers }) ``` -------------------------------- ### Migration from Redux Toolkit: useSeblak and useSeblakSelector Source: https://github.com/zakirkun/seblak/blob/main/README.md Migration example from Redux Toolkit to Seblak. Use useSeblak to get state and actions, and useSeblakSelector to select data from the store. ```tsx // Redux Toolkit const dispatch = useDispatch() const users = useSelector(state => state.users) // Seblak equivalent const [state, actions] = useSeblak(userStore) const users = useSeblakSelector(userStore, state => state.data.users) ``` -------------------------------- ### createStore(options) Source: https://github.com/zakirkun/seblak/blob/main/README.md Creates a new store instance with initial state and optional name. ```APIDOC ## createStore(options) ### Description Creates a new store instance. ### Parameters - **options** (object) - Required - Configuration options for the store. - **initialState** (object) - Required - The initial state of the store. - **name** (string) - Optional - Name of the store for debugging purposes. ### Returns A store instance. ### Example ```tsx const store = createStore({ initialState: { /* your initial state */ }, name: 'optional-store-name' // for debugging }) ``` ``` -------------------------------- ### Optimization tips with selectors, debounce, and prefetch Source: https://github.com/zakirkun/seblak/blob/main/README.md Optimization tips: use selectors to avoid re-renders, debounce mutations with useMemo, and prefetch data with prefetchQuery. ```tsx // Use selectors to prevent unnecessary re-renders const count = useSeblakSelector(store, state => state.data.count) // Debounce mutations const { mutate } = useMutation({ mutationFn: useMemo(() => debounce(updateUser, 300), []) }) // Prefetch data const queryClient = useQueryClient() queryClient.prefetchQuery(['users'], fetchUsers) ``` -------------------------------- ### createAsyncStore(options) Source: https://github.com/zakirkun/seblak/blob/main/README.md Creates an async store with built-in data fetching capabilities. ```APIDOC ## createAsyncStore(options) ### Description Creates an async store with built-in data fetching. ### Parameters - **options** (object) - Required - Configuration options for the async store. - **fetcher** (function) - Required - Async function that returns a Promise of data. - **initialState** (DataType) - Optional - Initial data. - **name** (string) - Optional - Name for debugging. - **staleTime** (number) - Optional - Staleness timeout (default: 5min). - **cacheTime** (number) - Optional - Cache timeout (default: 10min). - **retry** (number | function) - Optional - Retry attempts (default: 3). - **retryDelay** (number | function) - Optional - Retry delay (default: exponential). - **refetchOnWindowFocus** (boolean) - Optional - Auto-refetch on window focus (default: true). - **refetchOnReconnect** (boolean) - Optional - Auto-refetch on reconnect (default: true). - **onSuccess** (function) - Optional - Success callback. - **onError** (function) - Optional - Error callback. ### Returns An async store instance. ### Example ```tsx const store = createAsyncStore({ fetcher: () => Promise, initialState?: DataType, name?: string, staleTime?: number, cacheTime?: number, retry?: number | function, retryDelay?: number | function, refetchOnWindowFocus?: boolean, refetchOnReconnect?: boolean, onSuccess?: (data) => void, onError?: (error) => void }) ``` ``` -------------------------------- ### createAsyncStore: Create async store with data fetching Source: https://github.com/zakirkun/seblak/blob/main/README.md Creates an async store with built-in data fetching. Requires a fetcher function and supports optional configuration for staleTime, cacheTime, retry, retryDelay, refetchOnWindowFocus, refetchOnReconnect, onSuccess, and onError. ```tsx const store = createAsyncStore({ fetcher: () => Promise, // Required: async function initialState?: DataType, // Optional: initial data name?: string, // Optional: for debugging staleTime?: number, // Optional: staleness timeout (default: 5min) cacheTime?: number, // Optional: cache timeout (default: 10min) retry?: number | function, // Optional: retry attempts (default: 3) retryDelay?: number | function, // Optional: retry delay (default: exponential) refetchOnWindowFocus?: boolean, // Optional: auto-refetch (default: true) refetchOnReconnect?: boolean, // Optional: auto-refetch (default: true) onSuccess?: (data) => void, // Optional: success callback onError?: (error) => void // Optional: error callback }) ``` -------------------------------- ### useQuery(options) - Data fetching hook Source: https://github.com/zakirkun/seblak/blob/main/README.md Use this hook to fetch data with React Query-like behavior. It returns state fields like data, isLoading, isFetching, error, and functions like refetch and remove. Configure with queryKey, queryFn, staleTime (default 5min), cacheTime (default 10min), retry, enabled, refetchOnWindowFocus, and callbacks. ```tsx const { data, // Fetched data isLoading, // Initial loading state isFetching, // Any fetching state isRefetching, // Background refetching error, // Error message isError, // Boolean error state isSuccess, // Boolean success state lastFetched, // Timestamp refetch, // Refetch function remove // Remove from cache } = useQuery({ queryKey: ['users', userId], // Unique key queryFn: () => fetchUser(userId), // Fetch function staleTime: 60000, // Staleness (default: 5min) cacheTime: 300000, // Cache time (default: 10min) retry: 3, // Retry attempts enabled: true, // Auto-fetch enabled refetchOnWindowFocus: true, // Auto-refetch on focus onSuccess: (data) => {}, // Success callback onError: (error) => {} // Error callback }) ``` -------------------------------- ### createStore: Create a new store instance Source: https://github.com/zakirkun/seblak/blob/main/README.md Creates a new store instance with an initial state and an optional name for debugging. ```tsx const store = createStore({ initialState: { /* your initial state */ }, name: 'optional-store-name' // for debugging }) ``` -------------------------------- ### useInfiniteQuery(options) - Paginated data hook Source: https://github.com/zakirkun/seblak/blob/main/README.md Use this hook for paginated or infinite data. It returns data as { pages: [], pageParams: [] }, fetchNextPage, fetchPreviousPage, hasNextPage, hasPreviousPage, and fetching flags. Configure queryKey, queryFn with pageParam, and getNextPageParam/getPreviousPageParam to determine page cursors. ```tsx const { data, // { pages: [], pageParams: [] } fetchNextPage, // Fetch next page function fetchPreviousPage, // Fetch previous page function hasNextPage, // Boolean: has more pages hasPreviousPage, // Boolean: has previous pages isFetchingNextPage, // Loading next page isFetchingPreviousPage, // Loading previous page ...queryResult // All useQuery results } = useInfiniteQuery({ queryKey: ['posts'], queryFn: ({ pageParam = 0 }) => fetchPosts(pageParam), getNextPageParam: (lastPage, allPages) => lastPage.nextCursor, getPreviousPageParam: (firstPage, allPages) => firstPage.prevCursor }) ``` -------------------------------- ### useAsyncSeblak(store) Source: https://github.com/zakirkun/seblak/blob/main/README.md Hook for async store with additional async state and actions. ```APIDOC ## useAsyncSeblak(store) ### Description Hook for async store with additional async state. ### Parameters - **store** (AsyncStore) - Required - The async store instance created by `createAsyncStore`. ### Returns Returns a tuple `[state, actions]`. #### Additional Async State Properties - **isFetching** (boolean) - Currently fetching. - **isRefetching** (boolean) - Currently refetching. - **lastFetched** (timestamp) - Timestamp of last fetch. - **retryCount** (number) - Current retry attempt. #### Additional Async Actions - **fetch()** - Manual fetch. - **refetch()** - Force refetch. - **invalidate()** - Invalidate cache. - **retry()** - Retry failed request. - **mutate(data)** - Optimistic update. ### Example ```tsx const [state, actions] = useAsyncSeblak(store) ``` ``` -------------------------------- ### Utility hooks - useQueryClient, useInvalidateQueries, useRefetchQueries Source: https://github.com/zakirkun/seblak/blob/main/README.md Utility hooks for query client access, invalidation, and refetching. useQueryClient returns the client instance. useInvalidateQueries returns an invalidate function that accepts an optional query key array to invalidate specific or all queries. useRefetchQueries returns a refetch function with similar behavior. ```tsx // Get query client instance const queryClient = useQueryClient() // Invalidate queries const invalidate = useInvalidateQueries() invalidate(['users']) // Specific query invalidate() // All queries // Refetch queries const refetch = useRefetchQueries() refetch(['users']) // Specific query refetch() // All queries ``` -------------------------------- ### useSeblak(store) Source: https://github.com/zakirkun/seblak/blob/main/README.md Primary hook for accessing store state and actions. ```APIDOC ## useSeblak(store) ### Description Primary hook for accessing store state and actions. ### Parameters - **store** (Store) - Required - The store instance created by `createStore`. ### Returns Returns a tuple `[state, actions]`. #### State Properties - **data** - The actual state data. - **loading** (boolean) - Loading indicator. - **error** (string | null) - Error message. - **isStale** (boolean) - Data is stale (beyond staleTime). - **isCacheExpired** (boolean) - Data is expired (beyond cacheTime). #### Actions - **setState(partialState)** - Update state. - **setLoading(boolean)** - Set loading state. - **setError(string | null)** - Set error state. - **reset()** - Reset to initial state. ### Example ```tsx const [state, actions] = useSeblak(store) ``` ``` -------------------------------- ### TypeScript Support: Typed Stores and Query Hook Source: https://github.com/zakirkun/seblak/blob/main/README.md Shows Seblak's TypeScript type safety with typed stores and hooks. Use createStore with a generic type for synchronous state, createAsyncStore for async data with inferred fetcher return type, and useQuery with explicit generics for queries. ```tsx interface UserState { users: User[] selectedUser: User | null } // Fully typed store const userStore = createStore({ initialState: { users: [], selectedUser: null } }) // Type-safe async store const postsStore = createAsyncStore({ fetcher: () => fetchPosts() // Return type inferred }) // Generic query hook const { data } = useQuery({ queryKey: ['users'], queryFn: fetchUsers }) ``` -------------------------------- ### Custom retry logic with createAsyncStore Source: https://github.com/zakirkun/seblak/blob/main/README.md Configure custom retry behavior for an async store. The retry callback stops retrying on 404 errors and limits retries to 3 attempts; retryDelay uses exponential backoff capped at 30 seconds. ```tsx const store = createAsyncStore({ fetcher: fetchData, retry: (failureCount, error) => { // Custom retry logic if (error.status === 404) return false return failureCount < 3 }, retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000) }) ``` -------------------------------- ### useAsyncSeblak: Access async store state and actions Source: https://github.com/zakirkun/seblak/blob/main/README.md Hook for async store with additional async state properties (isFetching, isRefetching, lastFetched, retryCount) and async actions (fetch, refetch, invalidate, retry, mutate). ```tsx const [state, actions] = useAsyncSeblak(store) // Additional async state properties: // state.isFetching - currently fetching // state.isRefetching - currently refetching // state.lastFetched - timestamp of last fetch // state.retryCount - current retry attempt // Additional async actions: // actions.fetch() - manual fetch // actions.refetch() - force refetch // actions.invalidate() - invalidate cache // actions.retry() - retry failed request // actions.mutate(data) - optimistic update ``` -------------------------------- ### Memory management with query cleanup and cacheTime Source: https://github.com/zakirkun/seblak/blob/main/README.md Manage memory by automatically removing inactive queries on unmount and disabling caching for ephemeral data with cacheTime set to 0. ```tsx // Automatic cleanup useEffect(() => { return () => { queryClient.removeQueries(['inactive-data']) } }, []) // Manual cache control const store = createAsyncStore({ fetcher: fetchData, cacheTime: 0 // No caching for ephemeral data }) ``` -------------------------------- ### useMutation(options) - Mutation hook Source: https://github.com/zakirkun/seblak/blob/main/README.md Use this hook for data mutations. It returns mutate, data, error, isLoading, isError, isSuccess, and reset. Configure mutationFn and optional callbacks: onMutate (for optimistic updates), onSuccess, onError, and onSettled. ```tsx const { mutate, // Mutation function data, // Mutation result error, // Mutation error isLoading, // Mutation loading state isError, // Boolean error state isSuccess, // Boolean success state reset // Reset mutation state } = useMutation({ mutationFn: (variables) => updateUser(variables), onMutate: (variables) => { // Called before mutation // Good for optimistic updates }, onSuccess: (data, variables) => { // Called on successful mutation }, onError: (error, variables) => { // Called on failed mutation }, onSettled: (data, error, variables) => { // Called after mutation (success or error) } }) ``` -------------------------------- ### useSeblak: Access store state and actions Source: https://github.com/zakirkun/seblak/blob/main/README.md Primary hook for accessing store state and actions. Provides state properties like data, loading, error, isStale, and isCacheExpired, along with actions to update state, set loading, set error, and reset. ```tsx const [state, actions] = useSeblak(store) // state.data - your actual state // state.loading - loading indicator // state.error - error message // state.isStale - data is stale (beyond staleTime) // state.isCacheExpired - data is expired (beyond cacheTime) // actions.setState(partialState) - update state // actions.setLoading(boolean) - set loading state // actions.setError(string | null) - set error state // actions.reset() - reset to initial state ``` -------------------------------- ### Optimistic updates with useMutation Source: https://github.com/zakirkun/seblak/blob/main/README.md Perform optimistic updates with useMutation. Cancels outgoing queries, snapshots previous data, updates the cache optimistically, rolls back on error, and invalidates queries on settle. ```tsx const { mutate } = useMutation({ mutationFn: updateUser, onMutate: async (newUser) => { // Cancel outgoing refetches await queryClient.cancelQueries(['users']) // Snapshot previous value const previousUsers = queryClient.getQueryData(['users']) // Optimistically update queryClient.setQueryData(['users'], old => [...old, newUser]) return { previousUsers } }, onError: (err, newUser, context) => { // Rollback on error queryClient.setQueryData(['users'], context.previousUsers) }, onSettled: () => { // Always refetch after error or success queryClient.invalidateQueries(['users']) } }) ``` -------------------------------- ### Stale-while-revalidate with createAsyncStore Source: https://github.com/zakirkun/seblak/blob/main/README.md Shows stale-while-revalidate behavior with createAsyncStore and useAsyncSeblak. Data is fresh for 30s, stale for 5min, then expired. The component displays status, cache validity, and a fetching indicator. ```tsx // Stale-while-revalidate example const apiStore = createAsyncStore({ fetcher: () => fetchUserData(), staleTime: 30000, // 30s - data becomes stale cacheTime: 300000, // 5min - data expires from cache }) function UserComponent() { const [state, actions] = useAsyncSeblak(apiStore) // When data is fresh (0-30s): served immediately // When data is stale (30s-5min): old data shown instantly, new data fetched in background // When data is expired (5min+): loading state shown while fetching return (
Status: {state.isStale ? 'Stale' : 'Fresh'}
Cache: {state.isCacheExpired ? 'Expired' : 'Valid'}
Data: {state.data?.name}
{state.isFetching &&
🔄 Updating...
}
) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.