settingsCache.ts
1 import type { SettingSource } from './constants.js' 2 import type { SettingsJson } from './types.js' 3 import type { SettingsWithErrors, ValidationError } from './validation.js' 4 5 let sessionSettingsCache: SettingsWithErrors | null = null 6 7 export function getSessionSettingsCache(): SettingsWithErrors | null { 8 return sessionSettingsCache 9 } 10 11 export function setSessionSettingsCache(value: SettingsWithErrors): void { 12 sessionSettingsCache = value 13 } 14 15 /** 16 * Per-source cache for getSettingsForSource. Invalidated alongside the 17 * merged sessionSettingsCache — same resetSettingsCache() triggers 18 * (settings write, --add-dir, plugin init, hooks refresh). 19 */ 20 const perSourceCache = new Map<SettingSource, SettingsJson | null>() 21 22 export function getCachedSettingsForSource( 23 source: SettingSource, 24 ): SettingsJson | null | undefined { 25 // undefined = cache miss; null = cached "no settings for this source" 26 return perSourceCache.has(source) ? perSourceCache.get(source) : undefined 27 } 28 29 export function setCachedSettingsForSource( 30 source: SettingSource, 31 value: SettingsJson | null, 32 ): void { 33 perSourceCache.set(source, value) 34 } 35 36 /** 37 * Path-keyed cache for parseSettingsFile. Both getSettingsForSource and 38 * loadSettingsFromDisk call parseSettingsFile on the same paths during 39 * startup — this dedupes the disk read + zod parse. 40 */ 41 type ParsedSettings = { 42 settings: SettingsJson | null 43 errors: ValidationError[] 44 } 45 const parseFileCache = new Map<string, ParsedSettings>() 46 47 export function getCachedParsedFile(path: string): ParsedSettings | undefined { 48 return parseFileCache.get(path) 49 } 50 51 export function setCachedParsedFile(path: string, value: ParsedSettings): void { 52 parseFileCache.set(path, value) 53 } 54 55 export function resetSettingsCache(): void { 56 sessionSettingsCache = null 57 perSourceCache.clear() 58 parseFileCache.clear() 59 } 60 61 /** 62 * Plugin settings base layer for the settings cascade. 63 * pluginLoader writes here after loading plugins; 64 * loadSettingsFromDisk reads it as the lowest-priority base. 65 */ 66 let pluginSettingsBase: Record<string, unknown> | undefined 67 68 export function getPluginSettingsBase(): Record<string, unknown> | undefined { 69 return pluginSettingsBase 70 } 71 72 export function setPluginSettingsBase( 73 settings: Record<string, unknown> | undefined, 74 ): void { 75 pluginSettingsBase = settings 76 } 77 78 export function clearPluginSettingsBase(): void { 79 pluginSettingsBase = undefined 80 }