feat(use-react): a link addressed by route name, and stone dev starts again - #271
Open
evens-stone wants to merge 1 commit into
Open
feat(use-react): a link addressed by route name, and stone dev starts again#271evens-stone wants to merge 1 commit into
stone dev starts again#271evens-stone wants to merge 1 commit into
Conversation
…ts again Two things a browser found that no test could. `stone dev` has been dead for React applications since the build moved into this package: the generated entry imported `runDevServer` from `@stone-js/cli`, which stopped exporting it, and the application died on a SyntaxError before running a line. Reproduced on the published starter. The two tests covering that template asserted the import as a string, which is why they stayed green through the move; they check the specifier and the name against the module now. And `StoneLink` takes a route name. Writing a path in a component makes the component own what the router owns: the day the path changes, every link that spelt it out is wrong and nothing says so. `name` plus everything `router.generate()` accepts, generated by the router itself, so a link and a redirect built from the same name cannot disagree. `href` and `to` keep working. The resolution lives in `@stone-js/use-react-core` as `useLink`, because an anchor is a browser element and a route name is not: a React Native component calls the same hook and renders what it likes. That is also why a parameterised link is highlighted correctly for the first time: the selected class compared a generated `/notes/42` against the pattern `/notes/:id`, which are never equal. Also eight security advisories published since the last release, which the lockfile audit refused without a dependency having changed here: `browserslist` refreshed (direct, two high), and `fast-uri`, `qs` and `@xmldom/xmldom` pinned through overrides in the lockfile that owns each. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Two of the four reported bugs, verified and fixed. The other two are reported below rather than fixed, with the measurements that say why.
stone devhas been dead for React applicationsReproduced on the published starter, not read from the code:
The generated entry imported the runner from
@stone-js/cli. Both runners moved into this package when it took over the React build; the template kept naming the package it had left. It now imports from@stone-js/use-react/cli, which is where they are.One correction to the report: it has been broken since the build moved (0.8.11), not since 0.8.19. Which is worse, and says something: no test starts a dev server, and the generated file is only ever executed by one.
The two tests covering that template asserted the import as a string, so they stayed green right through the move. They check the specifier and the name against the module now, so moving or renaming a runner fails in the suite instead of at the first
stone devsomebody runs.StoneLinktakes a route nameWriting a path in a component makes the component own what the router owns: the day the path changes, every link that spelt it out is wrong and nothing says so. Everything
router.generate()accepts is a prop (params,query,hash,protocol,withDomain), and the generation is the router's own, so a link and a redirect built from the same name cannot disagree. A name nobody declared warns and renders inert instead of producing a broken address that looks fine.The resolution lives in
@stone-js/use-react-core, asuseLink— an anchor is a browser element and a route name is not, so a React Native component calls the same hook and renders whatever it likes:That split is also what fixes a bug nobody had reported: the selected class compared the generated
/notes/42against the current route's pattern/notes/:id, which are never equal, so a link to any parameterised route was never highlighted. A named link is compared by name and by the parameters it named; one naming no parameter is current for every value of them, which is what a nav highlight wants.hrefandtokeep working,tostill accepting a path orNavigateOptions. The props are a union, so the compiler asks for one of the three.What I did not fix, and why
SJ-68, i18n as a silent no-op in the browser: not reproduced. The stated mechanism is that
blueprint.set(i18nBlueprint)from a@Configurationdoes nothing. Measured on the published@stone-js/config: it deep-merges correctly,providersandkernel.middlewareconcatenated, everything else intact,stone.i18npresent. And@Configuration.configure()runs during setup, before the kernel reads providers. So something else is at work, most likely the configuration class not reaching the client bundle's module list, which would explain SSR translating while hydration does not. It needs the app: tell me whether that file is in the client bundle's modules and I will take it from there. Their own fix,@I18n()on the Application, is the sanctioned activation path anyway.SJ-69, a middleware alias resolving itself: already diagnosed, not silent. Measured: a middleware aliased
authwhose constructor asks forauthgetsContainerError: Circular dependency detected: SignedIn → SignedIn. The framework names it. Renaming the alias was the right fix.What I did find next door is real but is not what was reported, and I reverted it rather than ship it: two different bindings can claim the same alias and the second silently wins (measured). Overwriting is asserted deliberately by the existing suite, and forbidding it would break an application overriding a first-party service. In a primitive everything depends on, that is your call, not mine.
SJ-67,
@stone-js/mcp-devin the browser bundle: real, and my fix was wrong, so it is not here. Only two files touchnode:*, and the build config already claims to exclude browser stubs that do not exist. I wrote them, and measured the result: the browser bundle still carriednode:fs, because three other modules import those two files and rollup follows the graph whatever the input glob says. Excluding inputs is not enough; it needs a resolution override, designed and bundled-tested. Shipping abrowsercondition that still importsnode:fswould be a false promise, so I reverted.Also: eight security advisories
The lockfile audit refused, on both lockfiles, without a dependency having changed here.
browserslistis the one that matters, a direct dependency of@stone-js/use-reactwith two high advisories; its range already allowed the patch.fast-uri,qsand@xmldom/xmldomare transitive and pinned through overrides in the lockfile that owns each, since a nested lockfile does not inherit the root's.Verification
pnpm run verifygreen across the workspace.@stone-js/use-react-core119 tests withlink.tsat 100% on all four gauges,@stone-js/use-react272 tests.🤖 Generated with Claude Code