Skip to content

refactor: calculator.ts を分ける(範囲の読み取り・シートの前処理・型) - #189

Merged
isamu merged 1 commit into
mainfrom
refactor/split-calculator
Oct 21, 2026
Merged

isamu merged 1 commit into
mainfrom
refactor/split-calculator

Conversation

@isamu

@isamu isamu commented Oct 21, 2026

Copy link
Copy Markdown
Member

Summary

Splits calculator.ts, which scoria flags as god-file (over 500 lines). Behaviour does not change.

  • src/engine/rangeReading.ts: the range reads offered to a formula — getRangeValues, getRangeValuesRaw, getRangeValuesKeepingBlanks, countFilledCells, getRangeGrid — and the helpers they use.
    • They lived as closures inside openSheet. Now rangeReaders({ resolveSheetData, sourceSheetOf, evaluateValue }) builds them from what they need.
    • evaluateValue is defined later inside openSheet, so it is passed as a function that calls it.
  • src/engine/sheetPreparation.ts: preprocessDates, which turns dates written as text into serial numbers, and sheetsDateSource, where a date's display format is read from.
  • src/engine/openSheetTypes.ts: the types calculator.ts and rangeReading.ts share (CellPosition, OpenSheet, ResolvedSheetRef and others).
  • normalizeData stays in calculator.ts. It is public, and tests import it from there. Its doc comment had become separated from it and now sits on it again.

Items to Confirm

  • The one change beyond moving code: countFilledCells had repeated sourceSheetOf's body (which sheet's cells as written to read) inline; it now calls sourceSheetOf. The two are the same expression.
  • Behaviour is unchanged. Old (origin/main) and new were run side by side and compared:
    • every formula in the tests (corpusdiff.mts);
    • formulas over generated sheets;
    • cross-sheet reads over generated sheets (COUNTA, SUM, AVERAGE, SUMIF, COUNT over a whole column, ROWS, INDEX, TRANSPOSE, SUM of SORT, and reads of a sheet that does not exist), whose source cells mix blanks, ="", text, errors, numbers and a SEQUENCE that spills.
    • Every result was identical: values and errors.
  • The public exports are unchanged. The runtime export lists of src/engine/index.ts, src/index.ts and src/core/index.ts are the same on origin/main and here.
  • yarn lint, yarn typecheck, yarn build, yarn test, yarn test:engine, run-all-fixtures.ts, test:calculator and test:scripts pass. oxlint reports nothing.

User Prompt

🤖 Generated with Claude Code

work in GUIChatPluginSpreadsheet

…the shared types

rangeReading.ts builds a sheet's range reads from what they need (resolving a reference, the sheet as
written, evaluating a call); sheetPreparation.ts holds the date preprocessing and the date source for
display; openSheetTypes.ts the types the two share with calculator.ts. Code moved as it was, except
that countFilledCells calls sourceSheetOf, whose body it had repeated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@isamu

isamu commented Oct 21, 2026

Copy link
Copy Markdown
Member Author

CODEX VERDICT: LGTM
Read SHA: 7571ecd

Axis Result
correctness and edge cases none
security (injection / path traversal / code evaluation) none
tests: does a test go red if the new behaviour breaks none; yarn typecheck passed and yarn test:engine passed all 2,216 tests. Vitest could not start because the existing vite.config.ts uses __dirname under --configLoader runner.
API / schema / wire / on-disk compatibility none
consistency with the rest of the codebase none
i18n lockstep (src/lang has 8 locales) none; no locale changes are needed
TIER C behaviour preservation none
move fidelity none; the extracted functions match origin/main:src/engine/calculator.ts, and the factory only closes over resolveSheetData, sourceSheetOf, and the evaluateValue thunk
countFilledCells equivalence none; sourceSheetOf(range) is equivalent to the former inline splitSheetReference/sourceName lookup
ordering / TDZ none; rangeReaders construction only creates closures, so the evaluateValue thunk is not invoked before evaluateValue is initialized
public surface none; export lists of src/engine/index.ts, src/index.ts, and src/core/index.ts are unchanged, and normalizeData remains importable from calculator.ts
differential coverage none; the corpus, generated, and cross-sheet cases described reach the moved range readers, spill preparation, blank-aware/count reads, grid reads, date preparation, and cross-sheet state paths

FINDINGS COMPLETE: I read every hunk of the diff and this is every finding I have.

@@ -0,0 +1,142 @@
/**
@isamu
isamu merged commit f6922a8 into main Oct 21, 2026
17 checks passed
@isamu
isamu deleted the refactor/split-calculator branch October 21, 2026 07:08
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.

2 participants