cherry-studio/docs/en/references/data/cache-overview.md
fullex fb51df99d0 feat(cache): add template key support for useCache with type inference
- Add type utilities for template key matching (IsTemplateKey, ExpandTemplateKey, ProcessKey)
- Add InferUseCacheValue<K> for automatic value type inference from template patterns
- Update useCache hook to support template keys with default value fallback
- Extend ESLint rule to validate template key syntax (e.g., 'scroll.position:${id}')
- Update CacheService.get() docs: clarify | undefined return is intentional
  (developers need to know when value doesn't exist after deletion/TTL expiry)
- Update cache documentation with template key usage examples

BREAKING CHANGE: CacheService.get() now explicitly returns T | undefined
(was implicit before). Callers should use ?? defaultValue for fallback.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 12:23:19 +08:00

6.8 KiB

Cache System Overview

The Cache system provides a three-tier caching architecture for temporary and regenerable data across the Cherry Studio application.

Purpose

CacheService handles data that:

  • Can be regenerated or lost without user impact
  • Requires no backup or cross-device synchronization
  • Has lifecycle tied to component, window, or app session

Three-Tier Architecture

Tier Scope Persistence Use Case
Memory Cache Component-level Lost on app restart API responses, computed results
Shared Cache Cross-window Lost on app restart Window state, cross-window coordination
Persist Cache Cross-window + localStorage Survives app restarts Recent items, non-critical preferences

Memory Cache

  • Fastest access, in-process memory
  • Isolated per renderer process
  • Best for: expensive computations, API response caching

Shared Cache

  • Synchronized bidirectionally between Main and all Renderer windows via IPC
  • Main process maintains authoritative copy and provides initialization sync for new windows
  • New windows fetch complete shared cache state from Main on startup
  • Best for: window layouts, shared UI state

Persist Cache

  • Backed by localStorage in renderer
  • Main process maintains authoritative copy
  • Best for: recent files, search history, non-critical state

Key Features

TTL (Time To Live) Support

// Cache with 30-second expiration
cacheService.set('temp.calculation', result, 30000)

Hook Reference Tracking

  • Prevents deletion of cache entries while React hooks are subscribed
  • Automatic cleanup when components unmount

Cross-Window Synchronization

  • Shared and Persist caches sync across all windows
  • Uses IPC broadcast for real-time updates
  • Main process resolves conflicts

Type Safety

  • Fixed keys: Schema-based keys for compile-time checking (e.g., 'app.user.avatar')
  • Template keys: Dynamic patterns with automatic type inference (e.g., 'scroll.position:${id}' matches 'scroll.position:topic-123')
  • Casual methods: For completely dynamic keys with manual typing (blocked from using schema-defined keys)

Data Categories

Performance Cache (Memory tier)

  • Computed results from expensive operations
  • API response caching
  • Parsed/transformed data

UI State Cache (Shared tier)

  • Sidebar collapsed state
  • Panel dimensions
  • Scroll positions

Non-Critical Persistence (Persist tier)

  • Recently used items
  • Search history
  • User-customized but regenerable data

Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│ Renderer Process                                             │
│ ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│ │ useCache    │  │useSharedCache│ │usePersistCache│         │
│ └──────┬──────┘  └──────┬──────┘  └──────┬──────┘          │
│        │                │                │                   │
│        └────────────────┼────────────────┘                   │
│                         ▼                                    │
│              ┌─────────────────────┐                        │
│              │   CacheService      │                        │
│              │   (Renderer)        │                        │
│              └──────────┬──────────┘                        │
└─────────────────────────┼────────────────────────────────────┘
                          │ IPC (shared/persist only)
┌─────────────────────────┼────────────────────────────────────┐
│ Main Process            ▼                                    │
│              ┌─────────────────────┐                        │
│              │   CacheService      │                        │
│              │   (Main)            │                        │
│              └─────────────────────┘                        │
│              - Source of truth for shared/persist           │
│              - Broadcasts updates to all windows            │
└──────────────────────────────────────────────────────────────┘

Main vs Renderer Responsibilities

Main Process CacheService

  • Manages internal cache for Main process services
  • Maintains authoritative SharedCache with type-safe access (getShared, setShared, hasShared, deleteShared)
  • Provides getAllShared() for new window initialization sync
  • Handles IPC requests from renderers and broadcasts updates to all windows
  • Manages TTL expiration using absolute timestamps (expireAt) for precise cross-window sync

Renderer Process CacheService

  • Manages local memory cache and SharedCache local copy
  • Syncs SharedCache from Main on window initialization (async, non-blocking)
  • Provides ready state tracking via isSharedCacheReady() and onSharedCacheReady()
  • Broadcasts cache updates to Main for cross-window sync
  • Handles hook subscriptions and updates
  • Local TTL management for memory cache

Usage Summary

For detailed code examples and API usage, see Cache Usage Guide.

Key Types

Type Example Schema Example Usage Type Inference
Fixed key 'app.user.avatar': string get('app.user.avatar') Automatic
Template key 'scroll.position:${id}': number get('scroll.position:topic-123') Automatic
Casual key N/A getCasual<T>('my.key') Manual

API Reference

Method Tier Key Type
useCache / get / set Memory Fixed + Template keys
getCasual / setCasual Memory Dynamic keys only (schema keys blocked)
useSharedCache / getShared / setShared Shared Fixed keys only
getSharedCasual / setSharedCasual Shared Dynamic keys only (schema keys blocked)
usePersistCache / getPersist / setPersist Persist Fixed keys only