Skip to content

refactor: settings store の 11 setter を makeSetter factory で集約 #271

Description

@ymnao

背景

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 集約 (推奨)

zustandcreate() 内で 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 採用根拠

  1. 11 setter が完全に均一 pattern — key / save 関数 / value 型の 3 つを引数化するだけで表現可能。差分ゼロ (side effect / early-return / error handling いずれもなし)。
  2. net -25 行程度 (約 -55%) — 現状 11 × 3 行 = 33 行 → factory 8 行 + 11 × 1 行 = 19 行。
  3. generic factory で型安全K extends keyof SettingsValues により keyvalue の型対応を静的に保証。save 関数のシグネチャも (value: SettingsValues[K]) => Promise<void> で拘束するため、呼び出し側で saveXxx の型不整合があれば tsc error として即検出できる。
  4. scope file-privatemakeSettercreate() 内 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 は完全に一致 (呼び出し側 コンポーネントに変更なし)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions