Skip to content

feat(core): introduce LinterHost#1246

Merged
auvred merged 16 commits intoflint-fyi:mainfrom
auvred:linter-host
Jan 7, 2026
Merged

feat(core): introduce LinterHost#1246
auvred merged 16 commits intoflint-fyi:mainfrom
auvred:linter-host

Conversation

@auvred
Copy link
Copy Markdown
Member

@auvred auvred commented Jan 3, 2026

PR Checklist

Overview

fs.watch has a LOT of quirks and inconsistencies across different platforms. I tried to cover them all, although I definitely missed some edge cases. Also since watching is asynchronuous and callback-based, there may be race conditions like this one:

  • fs.watch is removed in favor of fs.watchFile
  • a file is created
  • fs.watchFile is established
  • the event isn't triggered

However, this is super rare case, I guess. As far as I understand, ts.sys doesn't handle this case either.

I tested this on Linux and in a Windows VM. It would be nice if someone with macOS could run the tests on their machine as well. Ideally, we should setup a test matrix accross these major platforms. Also, createDiskBackedLinterHost.test.ts probably should be converted to an integration test, since it's impure (it creates ephemeral directory in the nearest node_modules).

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Jan 3, 2026

🦋 Changeset detected

Latest commit: 0e6d382

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 21 packages
Name Type
@flint.fyi/core Minor
@flint.fyi/cli Patch
@flint.fyi/json Patch
@flint.fyi/md Patch
@flint.fyi/package-json Patch
@flint.fyi/plugin-astro Patch
@flint.fyi/plugin-browser Patch
@flint.fyi/plugin-flint Patch
@flint.fyi/plugin-jsx Patch
@flint.fyi/plugin-next Patch
@flint.fyi/plugin-node Patch
@flint.fyi/plugin-nuxt Patch
@flint.fyi/plugin-performance Patch
@flint.fyi/plugin-react Patch
@flint.fyi/plugin-solid Patch
@flint.fyi/plugin-spelling Patch
@flint.fyi/rule-tester Patch
@flint.fyi/text Patch
@flint.fyi/ts Patch
@flint.fyi/yaml Patch
@flint.fyi/site Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Jan 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
flint Ready Ready Preview, Comment Jan 5, 2026 7:05pm

@auvred auvred added the package: core Related to the core Flint package underlying all other packages and plugins. label Jan 3, 2026
Comment on lines +145 to +149
using _ = host.watchFile(filePath, onEvent, 10);

await sleep(50);

fs.writeFileSync(filePath, "first");
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sleep(50) is used to account for Windows slowness. Sometimes it can't set up the watchers in time before fs.writeFileSync is called.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've got to love having to develop on Windows... 🙃

Suggestion: how about moving the await sleep(50);s to a helper function like sleepIfNeeded() that only waits if the OS is Windows? That way we don't get 50ms delays on Linux and Mac.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that when tests are run for the entire workspace, they're executed in parallel, and CI needs these timeouts too: https://github.com/flint-fyi/flint/actions/runs/20680548741/job/59374155423#step:5:770 🤷

With these timeouts, it runs locally in ~3.5s, so it's not that slow after all.

Comment on lines +113 to +117
let unwatched = false;
const unwatchSelf = () => {
unwatched = true;
watcher.close();
};
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done for potential race conditions that cannot be reliably tested, where the watcher fires twice for the same file.

@barrymichaeldoyle
Copy link
Copy Markdown
Contributor

barrymichaeldoyle commented Jan 3, 2026

I'm on MacOS, I pulled your branch, everything builds fine but yeah unfortunately the tests do fail.

Dumping some screenshots, let me know if you need me to look into anything else further or try some things out for you 🤔

Edit: removed my sad unhelpful screenshots 😂

@lishaduck
Copy link
Copy Markdown
Member

I'm on MacOS, I pulled your branch, everything builds fine but yeah unfortunately the tests do fail.

Did you build it first? Those are all module-not-found errors which shouldn't be popping up from these changes at least 🤔

@auvred
Copy link
Copy Markdown
Member Author

auvred commented Jan 3, 2026

Thanks a lot! But these failures are unrelated to the linter host tests. Did you run pnpm i && pnpm build before running the tests?

@barrymichaeldoyle
Copy link
Copy Markdown
Contributor

Whoops, that's embarrassing. I may have run the tests before the node_module installs finished 😅

Reran them now and I see there's just 1 error.

Test Error

Copy link
Copy Markdown
Collaborator

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers from me, this is a great clean start. Nice! 🥇

TIL about the case swapping trick, very nifty.

@JoshuaKGoldberg JoshuaKGoldberg added the 1 approval One team member approved; we're now waiting for a second approval or for 2 business days to pass. label Jan 6, 2026
Copy link
Copy Markdown
Member

@lishaduck lishaduck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's certainly followups needed, but I think we can save them for a followup to unblock #1179?

Ideally, we should setup a test matrix accross these major platforms. Also, createDiskBackedLinterHost.test.ts probably should be converted to an integration test, since it's impure (it creates ephemeral directory in the nearest node_modules).

@auvred auvred merged commit 3561386 into flint-fyi:main Jan 7, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1 approval One team member approved; we're now waiting for a second approval or for 2 business days to pass. package: core Related to the core Flint package underlying all other packages and plugins.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 Feature: introduce Linter Host abstraction

4 participants