syncCacheState.ts
services/remoteManagedSettings/syncCacheState.ts
97
Lines
4004
Bytes
5
Exports
7
Imports
10
Keywords
What this is
This page documents one file from the repository and includes its full source so you can read it without leaving the docs site.
Beginner explanation
This file is one piece of the larger system. Its name, directory, imports, and exports show where it fits. Start by reading the exports and related files first.
How it is used
Start from the exports list and related files. Those are the easiest clues for where this file fits into the system.
Expert explanation
Architecturally, this file intersects with integrations, remote-bridge. It contains 97 lines, 7 detected imports, and 5 detected exports.
Important relationships
Detected exports
setSessionCacheresetSyncCachesetEligibilitygetSettingsPathgetRemoteManagedSettingsSyncFromCache
Keywords
settingssessioncacheutilssettingsjsoneligibledatacacheauthherecachedsettings
Detected imports
path../../utils/envUtils.js../../utils/fileRead.js../../utils/jsonRead.js../../utils/settings/settingsCache.js../../utils/settings/types.js../../utils/slowOperations.js
Source notes
This page embeds the full file contents. Small or leaf files are still indexed honestly instead of being over-explained.
Full source
/**
* Leaf state module for the remote-managed-settings sync cache.
*
* Split from syncCache.ts to break the settings.ts → syncCache.ts → auth.ts →
* settings.ts cycle. auth.ts sits inside the large settings SCC; importing it
* from settings.ts's own dependency chain pulls hundreds of modules into the
* eagerly-evaluated SCC at startup.
*
* This module imports only leaves (path, envUtils, file, json, types,
* settings/settingsCache — also a leaf, only type-imports validation). settings.ts
* reads the cache from here. syncCache.ts keeps isRemoteManagedSettingsEligible
* (the auth-touching part) and re-exports everything from here for callers that
* don't care about the cycle.
*
* Eligibility is a tri-state here: undefined (not yet determined — return
* null), false (ineligible — return null), true (proceed). managedEnv.ts
* calls isRemoteManagedSettingsEligible() just before the policySettings
* read — after userSettings/flagSettings env vars are applied, so the check
* sees config-provided CLAUDE_CODE_USE_BEDROCK/ANTHROPIC_BASE_URL. That call
* computes once and mirrors the result here via setEligibility(). Every
* subsequent read hits the cached bool instead of re-running the auth chain.
*/
import { join } from 'path'
import { getClaudeConfigHomeDir } from '../../utils/envUtils.js'
import { readFileSync } from '../../utils/fileRead.js'
import { stripBOM } from '../../utils/jsonRead.js'
import { resetSettingsCache } from '../../utils/settings/settingsCache.js'
import type { SettingsJson } from '../../utils/settings/types.js'
import { jsonParse } from '../../utils/slowOperations.js'
const SETTINGS_FILENAME = 'remote-settings.json'
let sessionCache: SettingsJson | null = null
let eligible: boolean | undefined
export function setSessionCache(value: SettingsJson | null): void {
sessionCache = value
}
export function resetSyncCache(): void {
sessionCache = null
eligible = undefined
}
export function setEligibility(v: boolean): boolean {
eligible = v
return v
}
export function getSettingsPath(): string {
return join(getClaudeConfigHomeDir(), SETTINGS_FILENAME)
}
// sync IO — settings pipeline is sync. fileRead and jsonRead are leaves;
// file.ts and json.ts both sit in the settings SCC.
function loadSettings(): SettingsJson | null {
try {
const content = readFileSync(getSettingsPath())
const data: unknown = jsonParse(stripBOM(content))
if (!data || typeof data !== 'object' || Array.isArray(data)) {
return null
}
return data as SettingsJson
} catch {
return null
}
}
export function getRemoteManagedSettingsSyncFromCache(): SettingsJson | null {
if (eligible !== true) return null
if (sessionCache) return sessionCache
const cachedSettings = loadSettings()
if (cachedSettings) {
sessionCache = cachedSettings
// Remote settings just became available for the first time. Any merged
// getSettings_DEPRECATED() result cached before this moment is missing
// the policySettings layer (the `eligible !== true` guard above returned
// null). Flush so the next merged read re-merges with this layer visible.
//
// Fires at most once: subsequent calls hit `if (sessionCache)` above.
// When called from loadSettingsFromDisk() (settings.ts:546), the merged
// cache is still null (setSessionSettingsCache runs at :732 after
// loadSettingsFromDisk returns) — no-op. The async-fetch arm (index.ts
// setSessionCache + notifyChange) already handles its own reset.
//
// gh-23085: isBridgeEnabled() at main.tsx Commander-definition time
// (before preAction → init() → isRemoteManagedSettingsEligible()) reached
// getSettings_DEPRECATED() at auth.ts:115. The try/catch in bridgeEnabled
// swallowed the later getGlobalConfig() throw, but the merged settings
// cache was already poisoned. See managedSettingsHeadless.int.test.ts.
resetSettingsCache()
return cachedSettings
}
return null
}