Skip to content

refactor: settings/git-sync setter を createPersistedSetter に集約 + saveSetting 単一 SOT 化#277

Merged
ymnao merged 1 commit into
mainfrom
refactor/store-helpers-272
Jul 4, 2026
Merged

refactor: settings/git-sync setter を createPersistedSetter に集約 + saveSetting 単一 SOT 化#277
ymnao merged 1 commit into
mainfrom
refactor/store-helpers-272

Conversation

@ymnao

@ymnao ymnao commented Jul 2, 2026

Copy link
Copy Markdown
Owner

概要

Closes #272

settings store と git-sync store の永続化付き setter を共通 factory (createPersistedSetter) に集約する #272 対応。/code-review medium の副次的な指摘に沿って scope を広げ、22 個の save* wrapper を saveSetting 直呼びに集約 + commitMessage normalize の単一 SOT 化 + 内部 double cast の除去 + CLAUDE.md 戻り値型明示ルール準拠 を同時に対応した。

関連 Issue

Closes #272

移行 Stage

  • Stage 6: 仕上げ・配布・切り替え(内部品質改善のため実質的な stage 進行はなし)

変更内容

1. setter factory 集約 (#272 本体)

src/stores/store-helpers.tscreatePersistedSetter<TValues>(set, save)(key, normalize?) を新設。settings store (11 setter) と git-sync store (7 setter) の「normalize? → save → set({[key]: value})」共通 shape を hoist。setCommitMessage の normalize は helper の第 3 引数として渡す。

2. 22 個の save* wrapper を saveSetting 直呼びに集約

src/lib/store.ts の 22 個の 1 行 wrapper (saveShowLineNumbers / saveCommitMessage 等) を全て削除し、saveSetting を export に昇格。

  • settings/git-sync store は createPersistedSettersaveSetting を bind
  • theme / AppLayout / useUpdateCheck は saveSetting("key", value) を直接呼ぶ

新 key 追加時に「1 行 wrapper を書いて import を並べる」ボイラープレートが不要に。

3. commitMessage normalize を単一 SOT 化

従来は save 側 (setCommitMessage 内 trim) と load 側 (lib/store.ts:168-172) の 2 箇所に v.trim() || DEFAULT が重複していた。片方だけ更新するとホワイトスペースのみの入力挙動が乖離する drift 事故要因。

normalizeCommitMessage(v: unknown): stringtypes/git-sync.ts に抽出し、load 側と save 側の両方から同関数を呼ぶ形に統一。

4. createPersistedSetter 内部の double cast を除去

  • 従来: set({ [key]: next } as unknown as Partial<TValues>) (TS2352 回避のため unknown 経由の double cast)
  • 新: const patch: Partial<TValues> = {}; patch[key] = next; set(patch); の patch-then-assign 形式で cast なしに書き換え

将来 TValues[K] の union 拡張が silently 通ってしまう脆さを消した。

5. 戻り値型明示 (CLAUDE.md ルール準拠)

createPersistedSetter が返す inner arrow に (value: TValues[K]): void => を明示。CLAUDE.md「戻り値には必ず型を明示する」に準拠。

6. テストの mock 簡素化

8 テストファイルの vi.mock("../lib/store", ...)saveSetting: vi.fn() だけの形に集約。src/lib/store.test.ts の 9 個の wrapper-specific describe を saveSetting 単体テスト + commitMessage normalize テストに置換。

動作確認

  • biome check
  • tsc --noEmit(web / node / e2e 全プロジェクト)
  • vitest run — 2225 passed / 2 skipped
  • electron-vite build
  • renderer-only e2e (sandbox 内 EPERM のため CI で確認)
  • 実 Electron 起動での目視確認 (ローカルは user 側で pnpm install 後に実施)

スクリーンショット

…Setting 単一 SOT 化 (#272)

## setter factory 集約 (#272 本体)

- src/stores/store-helpers.ts に createPersistedSetter<TValues>(set, save)(key, normalize?)
  を新設。settings store (11 setter) と git-sync store (7 setter) の
  「normalize? → save → set({[key]: value})」共通 shape を hoist した。
- git-sync setCommitMessage の normalize は helper の第 3 引数として渡す。

## 22 個の save* wrapper を saveSetting 直呼びに集約

- src/lib/store.ts の 22 個の 1 行 wrapper (saveShowLineNumbers /
  saveCommitMessage 等) を全て削除し、saveSetting を export に昇格。
- settings/git-sync store は createPersistedSetter へ saveSetting を bind、
  theme/AppLayout/useUpdateCheck は saveSetting("key", value) を直接呼ぶ形に統一。
- 新 key 追加時に「1 行 wrapper を書いて import を並べる」ボイラープレートが不要に。

## commitMessage normalize を単一 SOT 化

- 従来は save 側 (setCommitMessage 内 trim) と load 側 (lib/store.ts:168-172) の
  二箇所に `v.trim() || DEFAULT` が重複していた。片方だけ更新するとホワイトスペース
  のみの入力挙動が乖離する drift 事故要因。
- normalizeCommitMessage(v: unknown): string を types/git-sync.ts に抽出し、
  load 側と save 側の両方から同関数を呼ぶ形に統一。

## createPersistedSetter 内部の double cast を除去

- 従来: `set({ [key]: next } as unknown as Partial<TValues>)` (TS2352 回避のため
  unknown 経由の double cast)。
- 新: `const patch: Partial<TValues> = {}; patch[key] = next; set(patch);` の
  patch-then-assign 形式で cast なしに書き換え。将来 TValues[K] の union 拡張が
  silently 通ってしまう脆さを消した。

## 戻り値型明示 (CLAUDE.md ルール準拠)

- createPersistedSetter が返す inner arrow に `(value: TValues[K]): void =>` を
  明示。CLAUDE.md「戻り値には必ず型を明示する」に準拠。

## テストの mock 簡素化

- 8 テストファイルの `vi.mock("../lib/store", ...)` を `saveSetting: vi.fn()`
  だけの形に集約。src/lib/store.test.ts の 9 個の wrapper-specific describe を
  saveSetting 単体テスト + commitMessage normalize テストに置換。

## 検証

- biome / tsc(web,node,e2e) / vitest 2225 pass / electron-vite build 全 green。
@ymnao ymnao merged commit ea8ffe5 into main Jul 4, 2026
9 checks passed
@ymnao ymnao deleted the refactor/store-helpers-272 branch July 4, 2026 14:23
@ymnao ymnao mentioned this pull request Jul 5, 2026
7 tasks
ymnao added a commit that referenced this pull request Jul 5, 2026
- package.json の version を 0.6.0 → 0.7.0 に bump
- CHANGELOG.md に v0.7.0 エントリを追加 (#243#280)
  - Fixed: FileTree scroll regression (#276)、electron e2e launch teardown timeout 拡大 (#247)
  - Internal: #209 3 項目 (drift-lock 系 refactor #278/#279/#280)、settings setter 集約 (#273#277)、search/workspace/backlink 系 helper 抽出 15 件
  - Dependencies: electron 43.0.0 / p-limit 7.3.0 major bump (#275)、Dependabot 7 件 combine (#274)、pnpm-workspace.yaml overrides で @codemirror dual copy を恒久防止

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: settings/git-sync store の setter 集約 helper を src/lib/store-helpers.ts に共通化

1 participant