背景
src/stores/settings.ts に定義された 11 setter (setShowLineNumbers / setFontSize / setAutoSaveDelay / setHighlightActiveLine / setFontFamily / setTrimTrailingWhitespace / setShowLinkCards / setScratchpadVolatile / setAutoUpdateCheck / setFileTreeShowHidden / setFileTreeExcludePatterns) は全て同一の 3 行 pattern:
setXxx: (value: T) => {
void saveXxx(value);
set({ xxx: value });
},
「save 関数呼出し (fire-and-forget) → 対応する zustand state を set」のみで、setter 間の差分は key 名 / save 関数 / value 型 の 3 つだけ。
Option A: makeSetter factory 集約 (推奨)
zustand の create() 内で set を捕捉する closure factory を定義:
export const useSettingsStore = create<SettingsState>()((set) => {
const makeSetter =
<K extends keyof SettingsValues>(
key: K,
save: (value: SettingsValues[K]) => Promise<void>,
) =>
(value: SettingsValues[K]) => {
void save(value);
set({ [key]: value } as Partial<SettingsState>);
};
return {
// ... initial values (11 個) ...
setShowLineNumbers: makeSetter("showLineNumbers", saveShowLineNumbers),
setFontSize: makeSetter("fontSize", saveFontSize),
setAutoSaveDelay: makeSetter("autoSaveDelay", saveAutoSaveDelay),
setHighlightActiveLine: makeSetter("highlightActiveLine", saveHighlightActiveLine),
setFontFamily: makeSetter("fontFamily", saveFontFamily),
setTrimTrailingWhitespace: makeSetter("trimTrailingWhitespace", saveTrimTrailingWhitespace),
setShowLinkCards: makeSetter("showLinkCards", saveShowLinkCards),
setScratchpadVolatile: makeSetter("scratchpadVolatile", saveScratchpadVolatile),
setAutoUpdateCheck: makeSetter("autoUpdateCheck", saveAutoUpdateCheck),
setFileTreeShowHidden: makeSetter("fileTreeShowHidden", saveFileTreeShowHidden),
setFileTreeExcludePatterns: makeSetter("fileTreeExcludePatterns", saveFileTreeExcludePatterns),
hydrate: (values: Partial<SettingsValues>) => set(values),
};
});
Option B: 現状維持
11 setter の 3 行 pattern をそのまま維持。
Option A 採用根拠
- 11 setter が完全に均一 pattern — key / save 関数 / value 型の 3 つを引数化するだけで表現可能。差分ゼロ (side effect / early-return / error handling いずれもなし)。
- net -25 行程度 (約 -55%) — 現状 11 × 3 行 = 33 行 → factory 8 行 + 11 × 1 行 = 19 行。
- generic factory で型安全 —
K extends keyof SettingsValues により key と value の型対応を静的に保証。save 関数のシグネチャも (value: SettingsValues[K]) => Promise<void> で拘束するため、呼び出し側で saveXxx の型不整合があれば tsc error として即検出できる。
- scope file-private —
makeSetter は create() 内 closure なので他 file から見えず、影響範囲は本 file 内完結。zustand の set 依存を helper に閉じ込められる。
参考: 直近セッションの同パターン
いずれも「1 file 内 file-private helper 抽出」で v0.7.0 milestone の「内部品質改善」型 refactor。本 issue も同カテゴリ。
対象ファイル
src/stores/settings.ts (現状 107 行、実装後 82 行前後)
既存 setter の外部 API は完全に一致 (呼び出し側 コンポーネントに変更なし)。
背景
src/stores/settings.tsに定義された 11 setter (setShowLineNumbers/setFontSize/setAutoSaveDelay/setHighlightActiveLine/setFontFamily/setTrimTrailingWhitespace/setShowLinkCards/setScratchpadVolatile/setAutoUpdateCheck/setFileTreeShowHidden/setFileTreeExcludePatterns) は全て同一の 3 行 pattern:「save 関数呼出し (fire-and-forget) → 対応する zustand state を set」のみで、setter 間の差分は key 名 / save 関数 / value 型 の 3 つだけ。
Option A:
makeSetterfactory 集約 (推奨)zustandのcreate()内でsetを捕捉する closure factory を定義:Option B: 現状維持
11 setter の 3 行 pattern をそのまま維持。
Option A 採用根拠
K extends keyof SettingsValuesによりkeyとvalueの型対応を静的に保証。save 関数のシグネチャも(value: SettingsValues[K]) => Promise<void>で拘束するため、呼び出し側でsaveXxxの型不整合があれば tsc error として即検出できる。makeSetterはcreate()内 closure なので他 file から見えず、影響範囲は本 file 内完結。zustand のset依存を helper に閉じ込められる。参考: 直近セッションの同パターン
workspace.tsのgetActiveTabhelper 抽出): 単一 file 内 helper 抽出、boilerplate 集約による品質改善。search.tsのprocessMdFilesParallelhelper 抽出): 3 caller 共通のPromise.all + ioLimitboilerplate を helper に集約。いずれも「1 file 内 file-private helper 抽出」で v0.7.0 milestone の「内部品質改善」型 refactor。本 issue も同カテゴリ。
対象ファイル
src/stores/settings.ts(現状 107 行、実装後 82 行前後)既存 setter の外部 API は完全に一致 (呼び出し側 コンポーネントに変更なし)。