Repository navigation
Core: Move the component-meta invalidation state machine into core - #35806
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdded shared project file tracking for path filtering, snapshot caching, versioning, root-file synchronization, and watcher invalidation. React component metadata extraction now uses this tracker and validates rewrites with unchanged modification times. ChangesProject File Tracking
Sequence Diagram(s)sequenceDiagram
participant ComponentMetaManager
participant ComponentMetaProject
participant ProjectFileTracker
participant ProjectFileSystem
ComponentMetaManager->>ComponentMetaProject: onFilesChanged(changes)
ComponentMetaProject->>ProjectFileTracker: invalidate changed files
ProjectFileTracker->>ProjectFileSystem: check mtimes and read snapshots
ProjectFileTracker-->>ComponentMetaProject: updated versions
ComponentMetaProject->>ProjectFileTracker: getSnapshot(filePath)
ProjectFileTracker-->>ComponentMetaProject: refreshed snapshot
Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
code/core/src/component-meta/ProjectFileTracker.ts (1)
189-190: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the provenance-only comment.
The
Adapted fromURL records origin. It does not explain a maintenance requirement. Delete it or replace it with a concise rationale for the implementation.As per coding guidelines, comments must explain maintenance-relevant rationale and must not contain provenance claims.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@code/core/src/component-meta/ProjectFileTracker.ts` around lines 189 - 190, Remove the provenance-only “Adapted from” comment and its URL near ProjectFileTracker; do not replace it unless a concise maintenance-relevant rationale is needed.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@code/core/src/component-meta/ProjectFileTracker.ts`:
- Around line 35-45: Normalize all path inputs consistently in
ProjectFileTracker: apply the existing path normalization to initial and
refreshed commandLine.fileNames, and to public getSnapshot/getScriptVersion
inputs. Use the normalized key for snapshots, fileVersions, and filesystem
calls, including onFilesChanged and ensureFresh, so every tracker state lookup
and update uses the same path representation.
- Around line 20-22: Update filterSourceFilePaths to exclude paths only when
node_modules is a complete normalized path segment, rather than matching the
substring anywhere; retain valid paths such as node_modules-tools/Tag.tsx.
In
`@code/renderers/react/src/componentManifest/componentMeta/ComponentMetaManager.test.ts`:
- Around line 247-290: Convert this regression test to use memfs instead of a
host temporary directory: add a top-level node:fs mock with spy enabled,
configure the mocked filesystem APIs with vi.mocked(), and reset and seed vol in
beforeEach. Update the test setup and file operations around
ComponentMetaManager and the timestamp assertions to operate on the memfs volume
while preserving the same coarse-mtime scenario and expectations.
---
Nitpick comments:
In `@code/core/src/component-meta/ProjectFileTracker.ts`:
- Around line 189-190: Remove the provenance-only “Adapted from” comment and its
URL near ProjectFileTracker; do not replace it unless a concise
maintenance-relevant rationale is needed.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 88b463ac-efc4-4ac3-bc24-d3367fa767a2
📒 Files selected for processing (7)
code/core/src/component-meta/ProjectFileTracker.tscode/core/src/component-meta/index.tscode/core/src/component-meta/types.tscode/renderers/react/src/componentManifest/componentMeta/ComponentMetaManager.test.tscode/renderers/react/src/componentManifest/componentMeta/ComponentMetaManager.tscode/renderers/react/src/componentManifest/componentMeta/ComponentMetaProject.tscode/renderers/react/src/componentManifest/componentMeta/componentMetaExtractor.test-helpers.ts
Package BenchmarksCommit: No significant changes detected, all good. 👏 |
88ed261 to
d8bd95f
Compare
d8bd95f to
a6efdc2
Compare
Both the React and the Angular component-meta analyzers keep one TypeScript LanguageService per matched tsconfig, and both need the same thing from it: which files the project claims, what version each is on, when a change event invalidates a snapshot, and how to stay fresh when an edit races the debounced watcher. React had all of that inline. `ProjectFileTracker` owns it once. React loses about 150 lines of it and reads the same behaviour back; the Angular analyzer arriving next consumes it instead of writing a second copy. The tracker deliberately knows nothing about either renderer: it takes a structural `ProjectFileSystem` rather than importing `typescript`, so `typeof ts` satisfies it without core naming the package.
`getSnapshot` and `getScriptVersion` read `snapshots` and `fileVersions` with the raw path while every other entry point normalized first, so the class had two possible keys for one file and a reader had to track which method did which. Normalize in both readers, and match `node_modules` as a whole path segment so a source directory like `src/node_modules-tools/` is no longer dropped from watcher discovery. `commandLine.fileNames` needs no normalizing here: `parseTsconfigCommandLine` already does it for every project the manager builds.
Co-authored-by: Valentin Palkovic <dev@valentinpalkovic.dev>
The JSDoc header had its continuation markers at column 0, which oxfmt rejects, so `format-check` was failing. While in there, applied the repo's own comment guidance to this file and to `ProjectFileTracker`. Pinned upstream permalinks with line ranges are named in AGENTS.md as noise that rots, and four of them here already point at a commit-pinned range that no longer means anything; they now name the upstream construct instead. The header listed the extraction paths as an implementation outline, so it says why props come from the story rather than what the code does. Em dashes swapped for hyphens per the house rule.
a6efdc2 to
30e3af7
Compare
checkRootFilesUpdate compared the freshly parsed command line's fileNames against the normalized fileNames already stored on the tracker, and stored the un-normalized ones back on a match failure. Windows-separator paths from a fresh ts.sys parse would never equal their forward-slash counterparts, causing spurious project version bumps, and un-normalized paths would then leak into getScriptFileNames().
toBeGreaterThan(0) also passed if unref() ran after only one of the two constructor listeners attached; toBe(2) makes the test catch that ordering regression.
Adds slash() and isInNodeModules() to core's shared utils, exported from storybook/internal/common, and replaces the hand-rolled copies in component-meta, the module-graph service, addon-mcp and the Vue docgen project manager.
Note
Stacked on #35750. That one records per-component docgen baselines from built sandboxes; this one lifts React's component-meta invalidation state machine into core, so the Angular analyzer in #35805 consumes it instead of writing a second copy.
What I did
React's component-meta analyzer keeps one TypeScript
LanguageServiceper matched tsconfig. The Angular analyzer arriving in the next slice needs exactly the same thing, and the same four answers from it: which files the project claims, what version each file is on, when a change event invalidates a cached snapshot, and how to stay fresh when an editor save races the debounced watcher.All of that was inline in React. This moves it into
storybook/internal/component-metaasProjectFileTracker, so there is one implementation rather than two drifting ones.The tracker knows nothing about either renderer. It takes a structural
ProjectFileSystemrather than importingtypescript, sotypeof tssatisfies it and core never names the package:How this is measured
React's existing component-meta suite is the proof: it exercises the same invalidation paths through the extracted tracker, unchanged.
yarn test --project "@storybook/react"yarn nx run-many -t checkProjectFileSystemboundary is a compile-time claim, so the typecheck is part of the evidenceChecklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
This is a behaviour-preserving move with no user-facing surface, so the meaningful check is that React docgen still invalidates correctly:
yarn task sandbox --template react-vite/default-ts --start-from auto.storybook/main.ts, setfeatures: { experimentalDocgenServer: true }yarn storybook, open Example/Button → Docs and confirm the props table is populatedsrc/stories/Button.tsxand save. The table should gain the prop without a restart - that path is the tracker's freshness handling.Documentation
MIGRATION.MD
Internal module with no public export, so nothing user-facing to document.
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsDeclare whether manual QA will be needed for this PR during the next release, through
qa:neededorqa:skipMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.