Open Bug 2065643 (sessionstore-ts) Opened 22 days ago Updated 6 days ago

[meta] Enable TypeScript for all of browser/components/sessionstore

Categories

(Firefox :: Session Restore, task)

task

Tracking

()

People

(Reporter: dao, Unassigned)

References

(Depends on 2 open bugs)

Details

(Keywords: meta)

This effort puts every module in browser/components/sessionstore under the tree's TypeScript setup and gates it in CI. The directory is Session Restore: it tracks the windows, tabs and tab groups a user has open, persists that state to disk, and puts it back when Firefox starts again or when the user reopens something they closed. It has twenty modules, ending at a single 9.2k-line one that holds the session state in memory and exposes the API the rest of the front-end calls. The state itself is a JSON tree assembled piecemeal across those modules; a schema validates it on the way to disk, and nothing checked the code that builds it.

None of the machinery is new. Mark Banner built it for the address bar — the tree-wide TypeScript linter that gates every component, the compiler settings, and the convention for declaring types a checker cannot otherwise see — and this effort follows that road.

A checked contract catches defects that tests do not. This code fails quietly: a property that never reaches the saved state, a value read back under a name nothing writes, a branch that cannot run. The user sees a session that comes back missing something, not an error, and no test asserts on it.

That bites hardest in the state format. It is built up by assignment across twenty modules, round-tripped through disk, and read back with whatever properties a given session file happened to carry. A schema validates it at write time, which catches nothing on the way in or on the way back out. The comments describing those shapes were documentation only — a reader trusted them and a reviewer had no way to verify them.

Writing the shapes down as real types also makes them available to every component that touches session data. And this effort is the second consumer of the tab strip's new element declarations, which gives a hand-written contract the check it otherwise lacks.

What the checker has caught already

This is a running list rather than an audit: the largest module is not under the checker yet, so most of what it will find is still ahead.

  • Session Restore's debug logging never ran. The block that reports what is being collected and written was guarded by a property read off the wrong object, defined on a base class that never sets it, and compared the wrong way round — three mistakes stacked, so no amount of raising the log level produced any output. Filed as Bug 2067051; the fix gives the logging framework the level check it never had, so the seven places elsewhere in the tree that hand-roll the same comparison can use it instead.
  • Reopening all closed tabs from closed windows threw. The menu called a method by a name Session Restore does not define, one letter off from the real one and spelled correctly twice elsewhere in the same file. The call ran through the untyped lazy-loading object, so nothing had ever checked it. The regression shipped in February and is filed as Bug 2067068.
  • Comments that named an open tab where the value is a closed one. Session Restore keeps records of closed tabs and groups that resemble the live ones and are not interchangeable with them. Nothing was broken; a reader following the comment would have been.

Progress at a glance

Phase Goal Bug Status
Step 0 Convert SessionStore to a modern class 1892761 DONE
Step 1 Complete the documentation and publish an API reference 2065591 DONE
Step 2 Land the project file green and wire the CI gate 2065637 DONE
Step 3 Write the session state shapes down as checkable types 2065800 DONE
Step 4 Fix the debug logging that never ran 2067051 DONE
Step 5 Type the lazily-imported modules 2066120 DONE
Step 6 Finish typing the lazily-imported modules 2067072 DONE
Step 7 Adopt the tab strip's shared element declarations 2069194 DONE
Step 8 Build closed and saved tab groups as one shape 2069783 IN REVIEW
Step 9 Type-check the recently-closed menus 2065811 DONE
Step 10 Take the main module to zero and put it under the gate Not filed yet PLANNED

Checking it yourself

Two commands cover it. To check the code while working on it, run the project directly and read the type checker's own output. The argument is the directory holding the configuration:

./mach ts check browser/components/sessionstore

For CI's verdict, or for machine-readable output, run the linter, the same thing the gate runs. It takes any path, maps it to the project containing it, and runs that whole project:

./mach lint -l typescript browser/components/sessionstore

Measuring a module that is still excluded means deleting the exclusion list, not naming the module on the command line — the project checks exactly what its include list holds after exclusions are applied, so a path given on the command line is ignored. A full run takes about fourteen seconds. The documentation build is a third consumer of the same comments and rejects type expressions the checker accepts, so a definition added to the main module has to satisfy both, and ./mach doc --no-serve --no-open browser/components/sessionstore/docs is the check. ESLint's default output formatter crashes on the documentation rules in this directory, so pass -f json.

The gate will not see one dependency. This project includes a declaration file the tabbrowser owns. The linter attributes a changed file to the project it sits under, so editing that file runs the tabbrowser's project alone, and a change to it can break this one with no CI signal until something unrelated here changes. Re-run the check above after any tabbrowser change that touches those declarations.

References

See Also: → 1964610
Depends on: 2065638
See Also: → tabbrowser-ts
Alias: sessionstore-ts
Depends on: 2065800
Depends on: 2065811
See Also: → sessionstore-docs
Depends on: 2066120
Depends on: 2067051
Depends on: 2067068
Depends on: 2067072
No longer depends on: 2067068
No longer depends on: 2065638
Depends on: 2069194
Depends on: 2069783
Depends on: 2069784
You need to log in before you can comment on or make changes to this bug.