# Cache Schema Guide How to add fixed and template keys. Aligned with [Preference Schema Guide](./preference-schema-guide.md) and [Boot Config Schema Guide](./boot-config-schema-guide.md). ## Schemas | Schema | Tier | File | Default map | | ------------------------------- | ------------------ | --------------------------------------------------- | ----------------------------- | | `UseCacheSchema` | Memory | `src/shared/data/cache/cacheSchemas.ts` | `DefaultUseCache` | | `SharedCacheSchema` | Shared | `src/shared/data/cache/cacheSchemas.ts` | `DefaultSharedCache` | | `RendererPersistCacheSchema` | Persist (Renderer) | `src/shared/data/cache/cacheSchemas.ts` | `DefaultRendererPersistCache` | | `MainPersistCacheSchema` | Persist (Main) | `src/shared/data/cache/cacheSchemas.ts` | `DefaultMainPersistCache` | Complex value types go in `src/shared/data/cache/cacheValueTypes.ts` and are imported via `CacheValueTypes.*`. ## Naming Convention Enforced by ESLint rule `data-schema-key/valid-key`. Pattern: `/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/`. | Valid | Invalid | Why | | ------------------------------------- | -------------------------------- | --------------------------- | | `app.user.avatar` | `userAvatar` | No dot separator | | `chat.multi_select_mode` | `chat.multiSelectMode` | No camelCase | | `scroll.position.${topicId}` | `scroll.position:${id}` | Colon not allowed | | `entity.cache.${type}_${id}` | `App.user` | No uppercase | Template placeholders `${xxx}` are treated as literal segments for the naming check. At runtime, the placeholder **name** is ignored — `${providerId}` and `${foo}` produce identical regex; each placeholder expands to `[\w\-]+` (no dots, no colons, no non-ASCII). ## Choosing Fixed / Template / Casual | | Fixed key | Template key | Casual (Memory only) | | ------------------------- | ------------------- | ------------------- | -------------------- | | Type inference | Automatic | Automatic | Manual generic | | Compile-time validation | Yes | Yes | No | | Dynamic segments | No | Yes | Yes | | Shared tier | Yes | Yes | **Not supported** | | Persist tier | Yes | **Not supported** | **Not supported** | | Default value | Per key | Shared across instances | None | Prefer Fixed > Template > Casual. Cross-window dynamic keys must be Template — there is no `getSharedCasual`. ## Adding a Fixed Key ### 1. Add the entry ```typescript // src/shared/data/cache/cacheSchemas.ts export type UseCacheSchema = { // ...existing entries 'feature.my_feature.data': MyDataType } export const DefaultUseCache: UseCacheSchema = { // ...existing defaults 'feature.my_feature.data': { items: [], lastUpdated: 0 } } ``` ### 2. Define complex value type (if needed) ```typescript // src/shared/data/cache/cacheValueTypes.ts export interface MyDataType { items: string[] lastUpdated: number } ``` ### 3. Use it ```typescript const [data, setData] = useCache('feature.my_feature.data') // data is MyDataType ``` ## Adding a Template Key ```typescript // cacheSchemas.ts export type UseCacheSchema = { 'scroll.position.${topicId}': number } export const DefaultUseCache: UseCacheSchema = { 'scroll.position.${topicId}': 0 // shared by every concrete instance } ``` Use with any string in the dynamic segment: ```typescript const [pos, setPos] = useCache(`scroll.position.${topicId}`) // pos is number; default 0 for every topicId that hasn't been written yet ``` The placeholder name is documentation-only. `${topicId}` and `${id}` compile to the same runtime matcher. Pick a name that matches the concept (not convention). ## Shared and Persist Variants - Shared: add to `SharedCacheSchema` / `DefaultSharedCache`. Fixed and template both supported. - Persist: add to `RendererPersistCacheSchema` / `DefaultRendererPersistCache`. **Fixed keys only.** Persist values survive restart via localStorage — keep them small and typed. ## Validation | Check | Command / location | | ---------------------------- | ------------------------------------------------------ | | ESLint naming rule | `pnpm lint` (rule: `data-schema-key/valid-key`) | | Template matching unit tests | `src/shared/data/cache/__tests__/templateKey.test.ts` | | Schema exhaustiveness | TypeScript compiler — default map must satisfy the schema type | ## See Also - [Cache Overview](./cache-overview.md) — design invariants, tier semantics - [Cache Usage](./cache-usage.md) — hooks, direct API, patterns