Files
CherryHQ-cherry-studio/docs/references/data/cache-schema-guide.md
fullex c514dcc049 refactor(shared): move packages/shared to src/shared
packages/shared was never a real pnpm workspace package (no package.json); it was referenced only through the @shared TypeScript path alias. Relocate it under src/ via git mv (143 files, detected as pure renames).

Repoint the @shared alias and include globs to src/shared across electron.vite.config.ts, tsconfig.{json,node,web}.json and vitest.config.ts; update scripts/check-custom-exts.ts, scripts/update-languages.ts, the eslint.config.mjs generated-file globs, the data-classify generator output targets, .github/CODEOWNERS path rules, and CLAUDE.md/docs/source-comment references.

The @shared alias name is unchanged, so all 1403 @shared/* import sites resolve without modification. Verified with typecheck:node, typecheck:web and the full test suite (700 files, 9739 tests passing).
2026-05-28 21:02:49 -07:00

5.0 KiB

Cache Schema Guide

How to add fixed and template keys. Aligned with Preference Schema Guide and Boot Config Schema Guide.

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 src/shared/data/cache/cacheSchemas.ts DefaultRendererPersistCache

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

// 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)

// src/shared/data/cache/cacheValueTypes.ts
export interface MyDataType {
  items: string[]
  lastUpdated: number
}

3. Use it

const [data, setData] = useCache('feature.my_feature.data')
// data is MyDataType

Adding a Template Key

// 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:

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