unplugin: support SolidStart / vinxi filesystem routers#2148
Conversation
vinxi's filesystem routers enumerate a route module's exports by reading the file off disk and parsing it with esbuild's tsx loader, which fails on Civet source and silently drops the route. Wrap each router's toRoute to hand the analyzer compiled TSX instead, hooked from both the vite config hook and a construction-time microtask via globalThis.app (vinxi build materializes routes in the parent process without running any vite hook). Also stop appending the output extension to resolved ids under vinxi, since route chunks are looked up in vite's build manifest by the original .civet path, and warn on ts: "preserve", which nothing downstream can strip there. Adds a SolidStart example with page and API routes in Civet. Fixes #1319 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2148 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 57 57
Lines 28023 28134 +111
Branches 5255 5281 +26
==========================================
+ Hits 28023 28134 +111
🚀 New features to boost your workflow:
|
Greptile SummaryThis PR adds SolidStart/vinxi filesystem-router compatibility to the Civet unplugin. Two independent issues are fixed: vinxi's
Confidence Score: 5/5Safe to merge. The two root-cause fixes are well-scoped, the concurrency-sensitive fs.readFileSync intercept uses a correct Map+refcount pattern, and the change is covered by ten new unit tests. Both bugs are addressed with targeted, independently testable changes. The module-level readFileSync intercept correctly handles concurrent toRoute calls. The vinxi flag is set only from the vite config hook, which is intentional. No pre-existing behavior is altered for non-vinxi users. No files require special attention. Important Files Changed
Reviews (2): Last reviewed commit: "unplugin: review feedback — refcounted i..." | Re-trigger Greptile |
Concurrent toRoute calls (two routers analyzing in dev) could race the save/restore of the function pointer, leaving a stale patch installed. A single permanent intercept consults a substitution map instead, with synchronous set/delete around the analyzer's synchronous read. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
edemaine
left a comment
There was a problem hiding this comment.
Thanks for taking this on! Are you working on an upstream patch too?
I thought Tanstack Start used Vinxi, but apparently they migrated away last year. Nonetheless, we should probably test Tanstack Start with the unplugin at some point.
|
- Install the readFileSync intercept only while route analyses are in flight, restoring the original when the count returns to zero - Share one compile-options load between buildStart and vinxi route analysis via `compileOptions ?=`, with the threads merge inside the loader - Single fs default import (+ type-only Stats) instead of namespace + default pair Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@greptileai revise your review |
Fixes #1319 (same report as solid-start#1549).
Cause: two independent breaks.
analyzeModule) enumerate a route module's exports by reading the file raw off disk and parsing it with esbuild's tsx loader. Civet source fails to parse,addRouteswallows the error, and the route is silently dropped — before any vite plugin runs..civet→.civet.tsxid rewrite breaks vinxi's manifest correspondence: route chunks are looked up in vite's build manifest by the original.civet?pick=...path, crashing prod SSR withCannot read properties of undefined (reading 'file').Approach:
toRouteto compile.civetroutes to TSX and substitutefs.readFileSync(exact-path match, restored infinally) for the duration of the analysis. Hooked from the viteconfighook (enforce: 'pre'runs before vinxi's hook that first materializes routes) and from a construction-time microtask viaglobalThis.app, becausevinxi buildbuilds each router in a subprocess while the parent also materializes routes without running any vite hook.extensionsto vite-plugin-solid.ts: "preserve"under vinxi: with.civetids, neither vite core nor vite-plugin-solid strips TypeScript syntax, so output must be type-free (civet/esbuild/tsc).Includes a SolidStart example (
integration/unplugin-examples/solid-start) with a Civet page route and API route — verified withvinxi build+ serving the output, andvinxi dev— plus unit tests for the router patching and id behavior, and README/docs updates.Longer term this wants an upstream analysis hook (sketched in the linked solid-start issue discussion); this fix works without one and could feature-detect it later.
🤖 Generated with Claude Code