### Post-Creation Project Setup (CLI) Source: https://github.com/laofahai/linch-pc-base/blob/main/packages/create-linch-app/README.md Commands to run after a new Linch Desktop application has been created. This includes navigating into the project directory, installing dependencies, and starting the development server using Tauri. ```bash cd my-app pnpm install pnpm tauri:dev ``` -------------------------------- ### Create New Linch Desktop App (CLI) Source: https://github.com/laofahai/linch-pc-base/blob/main/packages/create-linch-app/README.md Command-line interface for creating a new Linch Desktop application. Supports interactive and non-interactive modes, allowing for customization of app name, display name, and identifier. This is the primary way to start a new project. ```bash npx @linch-tech/create-desktop-app my-app ``` ```bash npx @linch-tech/create-desktop-app my-app -y ``` ```bash npx @linch-tech/create-desktop-app my-app -y -d "My App Name" -i "com.company.myapp" ``` -------------------------------- ### Interact with SQLite Database API - TypeScript Source: https://context7.com/laofahai/linch-pc-base/llms.txt Provides examples of using the database API from '@linch-tech/desktop-core' for SQLite operations. This includes initialization with migrations, querying, executing statements, managing transactions, and handling settings and app state. ```typescript import { initDatabase, query, execute, transaction, getSetting, setSetting, getAppState, setAppState, baseMigrations, } from '@linch-tech/desktop-core'; // Initialize with custom migrations await initDatabase({ name: 'app.db', migrations: [ ...baseMigrations, { version: 10, name: 'create_users_table', up: `CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT UNIQUE, created_at INTEGER DEFAULT (strftime('%s', 'now')) )`, down: 'DROP TABLE users', }, ], }); // Query data const users = await query<{ id: number; name: string; email: string }>( 'SELECT * FROM users WHERE name LIKE ?', ['%john%'] ); console.log(users); // [{ id: 1, name: 'John Doe', email: 'john@example.com' }] // Execute INSERT/UPDATE/DELETE const result = await execute( 'INSERT INTO users (name, email) VALUES (?, ?)', ['Jane Doe', 'jane@example.com'] ); console.log(result); // { rowsAffected: 1, lastInsertId: 2 } // Transaction support await transaction(async (db) => { await execute('UPDATE accounts SET balance = balance - 100 WHERE id = ?', [1]); await execute('UPDATE accounts SET balance = balance + 100 WHERE id = ?', [2]); }); // Settings API (key-value storage) await setSetting('theme', 'dark'); await setSetting('user', { name: 'John', preferences: { notifications: true } }); const theme = await getSetting('theme'); // 'dark' const user = await getSetting<{ name: string }>('user'); // { name: 'John', ... } // App State API (for UI state persistence) await setAppState('sidebar_collapsed', true); await setAppState('last_viewed_page', '/dashboard'); const collapsed = await getAppState('sidebar_collapsed'); // true ``` -------------------------------- ### Initialize linch_tech_desktop_core in Tauri App lib.rs Source: https://github.com/laofahai/linch-pc-base/blob/main/packages/tauri/README.md This Rust code snippet demonstrates how to integrate the linch_tech_desktop_core library into a Tauri application's main entry point (`lib.rs`). It imports the `run` function from the core library and calls it within the Tauri application's `main` function, making the core functionalities available. This requires a Tauri project setup. ```rust use linch_tech_desktop_core::run; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn main() { run(); } ``` -------------------------------- ### HTTP API Client Source: https://context7.com/laofahai/linch-pc-base/llms.txt Provides a type-safe HTTP client with Zod schema validation, timeout handling, and configurable base URL. It allows for making GET and POST requests, with optional schema validation for responses. A separate client can be created for different services. ```APIDOC ## HTTP API Client ### Description Type-safe HTTP client with Zod schema validation, timeout handling, and configurable base URL. ### Method GET, POST ### Endpoint `/users/{id}` (example path parameter) ### Parameters #### Query Parameters - **schema** (ZodSchema) - Optional - Zod schema for response validation. #### Request Body - **name** (string) - Required - User's name. - **email** (string) - Required - User's email address. ### Request Example ```typescript // GET request const user = await api.get<{ id: number; name: string }>('/users/1'); // POST request with body const newUser = await api.post('/users', { name: 'John', email: 'john@example.com' }); // With Zod schema validation const UserSchema = z.object({ id: z.number(), name: z.string(), email: z.string().email(), }); const validatedUser = await api.get('/users/1', { schema: UserSchema }); ``` ### Response #### Success Response (200) - **id** (number) - The user's ID. - **name** (string) - The user's name. - **email** (string) - The user's email address (if schema includes it). #### Response Example ```json { "id": 1, "name": "John Doe", "email": "john.doe@example.com" } ``` ### Error Handling Exceptions of type `ApiException` can be caught to handle errors, providing access to `status`, `message`, and `data`. ### Type-safe Endpoint Definitions `defineEndpoint` allows for creating strongly-typed API endpoints. ```typescript const getUser = defineEndpoint<{ id: string; }, void, { id: number; name: string; }>({ method: 'GET', path: (params) => `/users/${params.id}`, responseSchema: UserSchema, }); const user = await getUser(api, { id: '123' }); ``` ``` -------------------------------- ### Application Update Management Hook - React/TypeScript Source: https://context7.com/laofahai/linch-pc-base/llms.txt A React hook for managing application updates. It provides status tracking, progress reporting, and control over the update flow (check, download, install). It requires the '@linch-tech/desktop-core' library and can be enabled or disabled via a prop. ```tsx import { useUpdater } from '@linch-tech/desktop-core'; function UpdatePanel() { const { enabled, status, // 'idle' | 'checking' | 'available' | 'downloading' | 'ready' | 'up-to-date' | 'check-error' | 'download-error' updateInfo, // { available, version, currentVersion, body, date } progress, // { downloaded, total, percent } error, check, download, install, } = useUpdater({ enabled: true }); if (!enabled) return

Updater is disabled

; return (

Status: {status}

{status === 'idle' && ( )} {status === 'available' && updateInfo && (

New version available: {updateInfo.version}

Current: {updateInfo.currentVersion}

{updateInfo.body}

)} {status === 'downloading' && progress && (

Downloading: {progress.percent}%

)} {status === 'ready' && ( )} {error &&

Error: {error.message}

}
); } ``` -------------------------------- ### useUpdater Hook Source: https://context7.com/laofahai/linch-pc-base/llms.txt A React hook for managing application updates. It provides status tracking, progress reporting, and control over the check, download, and install flow for application updates. ```APIDOC ## useUpdater Hook ### Description Manage application updates with status tracking, progress reporting, and control over check/download/install flow. ### Parameters - **enabled** (boolean) - Optional - Whether the updater is enabled. Defaults to `true`. ### State Properties - **enabled** (boolean) - Indicates if the updater is enabled. - **status** (string) - Current status of the update process. Possible values: `'idle'`, `'checking'`, `'available'`, `'downloading'`, `'ready'`, `'up-to-date'`, `'check-error'`, `'download-error'`. - **updateInfo** (object | null) - Information about the available update, including `available`, `version`, `currentVersion`, `body`, and `date`. - **progress** (object | null) - Download progress details, including `downloaded`, `total`, and `percent`. - **error** (Error | null) - Any error encountered during the update process. ### Methods - **check()**: Initiates a check for available updates. - **download()**: Starts downloading the available update. - **install()**: Installs the downloaded update and restarts the application. ### Example Usage ```tsx import { useUpdater } from '@linch-tech/desktop-core'; function UpdatePanel() { const { status, updateInfo, progress, error, check, download, install } = useUpdater({ enabled: true }); if (!enabled) return

Updater is disabled

; return (

Status: {status}

{status === 'idle' && } {status === 'available' && updateInfo && (

New version available: {updateInfo.version}

)} {status === 'downloading' && progress && (

Downloading: {progress.percent}%

)} {status === 'ready' && } {error &&

Error: {error.message}

}
); } ``` ``` -------------------------------- ### Configure Tauri Rust Backend with Plugins (Rust) Source: https://context7.com/laofahai/linch-pc-base/llms.txt Sets up the Tauri Rust backend by integrating required plugins using an extension trait. It demonstrates how to configure the 'linch-tech-desktop-core' package, including options for Sentry integration and manual configuration, or using default plugins. ```rust // src-tauri/Cargo.toml [dependencies] linch_tech_desktop_core = "0.1" tauri = { version = "2", features = [...] } // src-tauri/src/lib.rs use linch_tech_desktop_core::{LinchDesktopExt, LinchConfig}; #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { // Option 1: Use from_env() to read VITE_SENTRY_DSN let config = LinchConfig::from_env(); // Option 2: Configure manually let config = LinchConfig::new() .sentry_dsn("https://xxx@sentry.io/xxx") .sentry_sample_rate(0.5); tauri::Builder::default() .with_linch_desktop(config) // Adds all plugins + Sentry .invoke_handler(tauri::generate_handler![ // your custom commands ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); // Option 3: Only plugins without Sentry tauri::Builder::default() .with_linch_plugins() // SQL, Updater, Shell, Dialog, Opener, Process, FS .run(tauri::generate_context!()) .expect("error"); // Option 4: Use helper function linch_tech_desktop_core::create_builder() .run(tauri::generate_context!()) .expect("error"); // Get core version from frontend use linch_tech_desktop_core::commands::get_linch_core_version; tauri::Builder::default() .invoke_handler(tauri::generate_handler![get_linch_core_version]) ``` -------------------------------- ### Initialize Application with LinchDesktopProvider Source: https://context7.com/laofahai/linch-pc-base/llms.txt The LinchDesktopProvider wraps your entire React application, initializing core services like database, i18n, and Sentry, while applying theme configurations. It requires a configuration object defining branding, navigation, features, internationalization, and database settings. ```tsx import { LinchDesktopProvider, Shell, SettingsPage } from '@linch-tech/desktop-core'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { Home, Settings } from 'lucide-react'; import Dashboard from './pages/Dashboard'; const config = { brand: { name: 'app.name', // i18n key version: 'v1.0.0', }, nav: [ { title: 'nav.home', path: '/', icon: Home }, { title: 'settings.title', path: '/settings', icon: Settings }, ], features: { updater: true, database: true, sentry: false, }, i18n: { defaultLanguage: 'en', supportedLanguages: ['en', 'zh'], resources: { en: { app: { name: 'My App' }, nav: { home: 'Home' } }, zh: { app: { name: '我的应用' }, nav: { home: '首页' } }, }, }, database: { name: 'app.db', migrations: [], }, }; export default function App() { return ( }> } /> } /> ); } ``` -------------------------------- ### Scaffold New Desktop Application with CLI Source: https://context7.com/laofahai/linch-pc-base/llms.txt Use the Linch CLI to quickly scaffold a new Tauri v2 + React 19 desktop application. It pre-configures TypeScript, TailwindCSS, i18n, SQLite, and auto-updater. Supports interactive and non-interactive modes. ```bash # Interactive mode - prompts for app name, identifier, etc. npx @linch-tech/create-desktop-app my-app # Non-interactive mode with all options npx @linch-tech/create-desktop-app my-app -y -d "My Application" -i "com.company.myapp" # After creation cd my-app pnpm install pnpm tauri:dev ``` -------------------------------- ### Use Reactive Settings and App State Hooks - TSX Source: https://context7.com/laofahai/linch-pc-base/llms.txt Demonstrates the `useSetting` and `useAppState` hooks from '@linch-tech/desktop-core' for managing database settings and application state reactively. These hooks provide automatic loading, persistence, and error handling. ```tsx import { useSetting, useAppState } from '@linch-tech/desktop-core'; function SettingsPanel() { // useSetting - for user preferences const { value: theme, setValue: setTheme, isLoading, error } = useSetting('theme', { defaultValue: 'system', }); // useAppState - for UI state persistence const { state: sidebarOpen, setState: setSidebarOpen } = useAppState( 'sidebar_open', true ); if (isLoading) return
Loading...
; if (error) return
Error: {error.message}
; return (
); } ``` -------------------------------- ### i18n Configuration Source: https://context7.com/laofahai/linch-pc-base/llms.txt Configuration for internationalization using i18next. Supports automatic language detection and deep merging of base and application translations. ```APIDOC ## i18n Configuration ### Description Internationalization with i18next, automatic language detection, and deep merge of base and app translations. ### Configuration Options - **defaultLanguage** (string): The default language for the application. - **supportedLanguages** (string[]): An array of languages supported by the application. - **resources** (object): An object containing translation resources, keyed by language code. Each language object can have nested keys for different translation modules (e.g., `app`, `nav`). ### Initialization - **`initI18n(defaultLanguage, resources, supportedLanguages)`**: Manually initializes the i18n instance. - If using `LinchDesktopProvider`, configuration can be passed via its `config.i18n` property. ### Usage in Components - Use the `useTranslation` hook from `react-i18next` to access translation functions. - **`t(key, options)`**: Translates a given key. Options can include interpolation variables. - **`i18n.changeLanguage(language)`**: Changes the current language of the application. ### Dynamic Resource Loading - **`addI18nResources(language, newResources)`**: Adds new translation resources dynamically for a specific language. ### Base Resources - `baseResources` provides access to built-in resources, typically including common and settings modules. ### Example ```typescript import { initI18n, changeLanguage, getCurrentLanguage, addI18nResources, baseResources } from '@linch-tech/desktop-core'; import { useTranslation } from 'react-i18next'; // Configuration object const config = { i18n: { defaultLanguage: 'en', supportedLanguages: ['en', 'zh', 'ja'], resources: { en: { app: { name: 'My Application' }, nav: { home: 'Home', settings: 'Settings' }, }, zh: { app: { name: '我的应用' }, nav: { home: '首页', settings: '设置' }, }, }, }, }; // Manual initialization initI18n('en', config.i18n.resources, config.i18n.supportedLanguages); // Component using translations function MyComponent() { const { t } = useTranslation(); return

{t('app.name')}

; } // Changing language changeLanguage('zh'); // Getting current language const currentLang = getCurrentLanguage(); // Adding resources addI18nResources('en', { newKey: { value: 'New Value' } }); // Accessing base resources console.log(baseResources.en.translation.common.save); ``` ``` -------------------------------- ### Manage Theme with useTheme Hook - TSX Source: https://context7.com/laofahai/linch-pc-base/llms.txt Demonstrates the `useTheme` hook from '@linch-tech/desktop-core' for managing light, dark, or system themes. It provides theme state and a function to update the theme, with automatic persistence to localStorage and system theme detection. ```tsx import { useTheme } from '@linch-tech/desktop-core'; function ThemeToggle() { const { theme, setTheme } = useTheme(); // theme: 'light' | 'dark' | 'system' return (

Current theme: {theme}

); } ``` -------------------------------- ### Utilize Pre-configured Shadcn/UI Components (TypeScript/React) Source: https://context7.com/laofahai/linch-pc-base/llms.txt Leverages pre-configured shadcn/ui components within the desktop environment provided by '@linch-tech/desktop-core'. This enables quick integration of common UI elements like buttons, cards, dialogs, and navigation components. ```tsx import { Button, Badge, Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Input, Label, Progress, ScrollArea, Separator, Switch, Tabs, TabsList, TabsTrigger, TabsContent, Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, PageHeader, ThemeSwitcher, LanguageSwitcher, Logo, WindowControls, SettingsPage, } from '@linch-tech/desktop-core'; function ComponentShowcase() { return (
User Profile Manage your account settings
General Advanced General settings content Advanced settings content
Default Secondary Destructive
); } ``` -------------------------------- ### Control Native Window Programmatically (TypeScript) Source: https://context7.com/laofahai/linch-pc-base/llms.txt Enables programmatic control of the native window, such as minimizing, maximizing, closing, and initiating drag operations. It relies on the '@linch-tech/desktop-core' package and exposes functions for window management and direct access to the Tauri window API. ```typescript import { appWindow, minimizeWindow, toggleMaximize, isMaximized, closeWindow, startDragging, } from '@linch-tech/desktop-core'; // Minimize window await minimizeWindow(); // Toggle maximize/restore await toggleMaximize(); // Check if maximized const maximized = await isMaximized(); console.log(maximized); // true or false // Close window await closeWindow(); // Start window dragging (call on mousedown of draggable area)
startDragging()}> Drag me to move window
// Direct access to Tauri window API await appWindow.setTitle('New Title'); await appWindow.setResizable(false); ``` -------------------------------- ### Implement Layout with Shell Component Source: https://context7.com/laofahai/linch-pc-base/llms.txt The Shell component provides the main application layout, including a sidebar navigation and content area. It supports customization of sidebar width and position, title bar height, and window controls. It also allows for slot injection for custom header, footer, and other content areas. ```tsx import { Shell, useConfig } from '@linch-tech/desktop-core'; import { Outlet } from 'react-router-dom'; // Basic usage - renders Outlet for nested routes }> } /> // With custom content (noOutlet mode)
Direct children content
// Configuration with slots and layout options const config = { layout: { sidebar: { width: 200, position: 'left', // or 'right' }, titleBar: { height: 40, showWindowControls: true, draggable: true, }, }, slots: { sidebar: { header:
Custom Header
, footer:
Custom Footer
, beforeNav: , afterNav: , }, shell: { beforeContent: , afterContent: , }, }, }; ``` -------------------------------- ### Internationalization (i18n) Configuration - TypeScript/React Source: https://context7.com/laofahai/linch-pc-base/llms.txt Configuration for internationalization using i18next, enabling automatic language detection and deep merging of translations. It supports defining multiple languages and resources, and allows dynamic addition of translations. The hook `useTranslation` from 'react-i18next' is used within components. ```typescript import { initI18n, changeLanguage, getCurrentLanguage, addI18nResources, baseResources, } from '@linch-tech/desktop-core'; import { useTranslation } from 'react-i18next'; // Configuration in LinchDesktopProvider config const config = { i18n: { defaultLanguage: 'en', supportedLanguages: ['en', 'zh', 'ja'], resources: { en: { app: { name: 'My Application' }, nav: { home: 'Home', settings: 'Settings' }, dashboard: { title: 'Dashboard', welcome: 'Welcome, {{name}}!' }, }, zh: { app: { name: '我的应用' }, nav: { home: '首页', settings: '设置' }, dashboard: { title: '仪表板', welcome: '欢迎,{{name}}!' }, }, }, }, }; // Manual initialization (if not using LinchDesktopProvider) initI18n('en', config.i18n.resources, config.i18n.supportedLanguages); // Use in components function Dashboard() { const { t, i18n } = useTranslation(); return (

{t('dashboard.title')}

{t('dashboard.welcome', { name: 'John' })}

Current language: {getCurrentLanguage()}

); } // Add resources dynamically addI18nResources('en', { newFeature: { title: 'New Feature' } }); // Base resources include: common.*, settings.* console.log(baseResources.en.translation.common.save); // "Save" console.log(baseResources.zh.translation.settings.title); // "设置" ``` -------------------------------- ### Debounce and Throttle Hooks in TypeScript Source: https://context7.com/laofahai/linch-pc-base/llms.txt Demonstrates the usage of `useDebounce`, `useDebouncedCallback`, `useThrottle`, and `useThrottledCallback` for managing input delays and event rate limiting. These hooks help optimize performance by controlling how frequently functions are executed in response to rapidly changing inputs or events. ```tsx import { useDebounce, useDebouncedCallback, useThrottle, useThrottledCallback, } from '@linch-tech/desktop-core'; function SearchComponent() { const [searchTerm, setSearchTerm] = useState(''); const debouncedSearch = useDebounce(searchTerm, 300); // Debounced callback const handleSearch = useDebouncedCallback((term: string) => { console.log('Searching for:', term); }, 300); // Throttled scroll handler const handleScroll = useThrottledCallback(() => { console.log('Scroll position:', window.scrollY); }, 100); return (
{ setSearchTerm(e.target.value); handleSearch(e.target.value); }} placeholder="Search..." /> {debouncedSearch &&

Searching: {debouncedSearch}

}
); } ``` -------------------------------- ### Async Operation Hooks in TypeScript Source: https://context7.com/laofahai/linch-pc-base/llms.txt Showcases the `useAsync` and `useFetch` hooks for handling asynchronous operations, including data fetching and state management for loading and error states. `useAsync` is a general-purpose hook for async logic, while `useFetch` is specifically tailored for making HTTP requests. ```tsx import { useAsync, useFetch, } from '@linch-tech/desktop-core'; interface User { id: number; name: string; } function DataFetchingComponent() { // Async operations with useAsync const { execute, data: asyncData, loading: asyncLoading, error: asyncError } = useAsync(async () => { const response = await fetch('/api/data'); return response.json(); }); // Data fetching with useFetch const { data: users, loading: fetchLoading, error: fetchError, refetch } = useFetch('/api/users'); return (

Async Data

{asyncError &&

Error: {asyncError.message}

} {asyncData &&
{JSON.stringify(asyncData, null, 2)}
}

User Data

{fetchLoading &&

Loading users...

} {fetchError &&

Error fetching users: {fetchError.message}

} {users && (
    {users.map(user =>
  • {user.name}
  • )}
)}
); } ``` -------------------------------- ### Add linch_tech_desktop_core Dependency to Cargo.toml Source: https://github.com/laofahai/linch-pc-base/blob/main/packages/tauri/README.md This snippet shows how to add the linch_tech_desktop_core library as a dependency in your Rust project's Cargo.toml file. It specifies the version of the library to be used. No external dependencies are required beyond a Rust development environment. ```toml [dependencies] linch_tech_desktop_core = "0.1" ``` -------------------------------- ### Configure Theme with CSS Variables - TypeScript Source: https://context7.com/laofahai/linch-pc-base/llms.txt Defines the theme configuration object in TypeScript, specifying colors, border radius, fonts, and custom CSS variables. Changes are applied at runtime using CSS custom properties. ```typescript const config = { theme: { colors: { primary: 'oklch(0.48 0.243 264.376)', secondary: 'oklch(0.65 0.15 240)', background: 'oklch(1 0 0)', foreground: 'oklch(0.2 0 0)', muted: 'oklch(0.95 0 0)', mutedForeground: 'oklch(0.5 0 0)', border: 'oklch(0.9 0 0)', ring: 'oklch(0.48 0.243 264.376)', accent: 'oklch(0.95 0.05 264)', accentForeground: 'oklch(0.2 0 0)', destructive: 'oklch(0.55 0.25 27)', destructiveForeground: 'oklch(1 0 0)', }, radius: 'md', // 'none' | 'sm' | 'md' | 'lg' | 'full' font: { sans: '"SF Pro Text", system-ui, sans-serif', mono: '"SF Mono", monospace', }, cssVariables: { sidebar: 'oklch(0.985 0 0)', 'custom-accent': '#ff6b6b', }, }, }; ``` -------------------------------- ### Event Handling Hooks in TypeScript Source: https://context7.com/laofahai/linch-pc-base/llms.txt Illustrates the use of `useClickOutside`, `useEscapeKey`, and `useClickOutsideOrEscape` for managing user interactions related to DOM elements and keyboard events. These hooks are essential for implementing features like dropdown menus, modals, and dismissible notifications. ```tsx import { useClickOutside, useEscapeKey, useClickOutsideOrEscape, } from '@linch-tech/desktop-core'; import { useRef, useState } from 'react'; function EventHandlingComponent() { const [isOpen, setIsOpen] = useState(true); const dropdownRef = useRef(null); useClickOutside(dropdownRef, () => setIsOpen(false)); useEscapeKey(() => setIsOpen(false)); useClickOutsideOrEscape(dropdownRef, () => setIsOpen(false)); return (
{isOpen && (

Content inside the clickable area.

)} {!isOpen && }
); } ``` -------------------------------- ### Local Storage Hook in TypeScript Source: https://context7.com/laofahai/linch-pc-base/llms.txt Demonstrates the `useLocalStorage` hook for managing state persisted in the browser's local storage. This hook provides a familiar useState-like interface for reading, writing, and updating values in local storage, simplifying data persistence across sessions. ```tsx import { useLocalStorage, } from '@linch-tech/desktop-core'; interface Preferences { theme: 'light' | 'dark' | 'system'; language: string; } function SettingsComponent() { const [preferences, setPreferences] = useLocalStorage('user_prefs', { theme: 'system', language: 'en', }); const toggleTheme = () => { setPreferences(prev => ({ ...prev, theme: prev.theme === 'dark' ? 'light' : 'dark', })); }; const changeLanguage = (lang: string) => { setPreferences(prev => ({ ...prev, language: lang })); }; return (

Settings

Current Theme: {preferences.theme}

Language: {preferences.language}

); } ``` -------------------------------- ### HTTP API Client with Zod Validation - TypeScript Source: https://context7.com/laofahai/linch-pc-base/llms.txt A type-safe HTTP client for making API requests. It supports Zod schema validation for response data, timeout handling, configurable base URLs, and custom headers. It's built using the '@linch-tech/desktop-core' library and can be extended to create clients for different services. ```typescript import { api, createApiClient, ApiException, defineEndpoint } from '@linch-tech/desktop-core'; import { z } from 'zod'; // Use default api instance (reads VITE_API_BASE_URL) api.setBaseUrl('https://api.example.com'); api.setHeader('Authorization', 'Bearer token123'); // GET request const user = await api.get<{ id: number; name: string }>('/users/1'); // POST request with body const newUser = await api.post('/users', { name: 'John', email: 'john@example.com' }); // With Zod schema validation const UserSchema = z.object({ id: z.number(), name: z.string(), email: z.string().email(), }); const validatedUser = await api.get('/users/1', { schema: UserSchema }); // Throws ApiException if response doesn't match schema // Create separate client for different service const billingApi = createApiClient({ baseUrl: 'https://billing.example.com', timeout: 60000, headers: { 'X-API-Key': 'secret' }, }); const invoices = await billingApi.get('/invoices'); // Error handling try { await api.get('/protected-resource'); } catch (error) { if (error instanceof ApiException) { console.log(error.status); // 401 console.log(error.message); // "Unauthorized" console.log(error.data); // Response body } } // Type-safe endpoint definitions const getUser = defineEndpoint<{ id: string }, void, { id: number; name: string }>({ method: 'GET', path: (params) => `/users/${params.id}`, responseSchema: UserSchema, }); const user = await getUser(api, { id: '123' }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.