fix: accept @dcl/hooks 2 as a peer - #474
Conversation
Deploying ui2 with
|
| Latest commit: |
721ba18
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5ed78062.ui2-423.pages.dev |
| Branch Preview URL: | https://fix-widen-hooks-peer-range.ui2-423.pages.dev |
34a58c1 to
f909b5e
Compare
decentraland-bot
left a comment
There was a problem hiding this comment.
Thanks for the clear write-up and for keeping the lockfile change minimal. The intent looks right: widening the peer contract to include @dcl/hooks@2 is a backward-compatible package metadata change for current consumers, and CI is green.
I found one issue that should be fixed before publishing this as the package contract.
Findings
- P1 — Major:
@dcl/hookspeer range is unbounded.>=1.2.1accepts every future major (3.x,4.x, etc.), sodecentraland-ui2would advertise compatibility with versions that have not been validated. Since this package importsuseAdvancedUserAgentData/AdvancedNavigatorUADatafrom@dcl/hooks, a future breaking major could become a silent downstream runtime/type failure instead of an npm peer warning. Please bound this to the known-compatible majors, e.g.^1.2.1 || ^2.0.0, and mirror it inpackage-lock.json.
Security
No PR-specific security issues found. npm audit reports existing high/moderate transitive vulnerabilities, but this PR does not add a new package or resolved dependency version.
Consumer impact
This is a public peer dependency contract change. Supporting v2 is backward-compatible for current consumers, but the unbounded range would unintentionally declare compatibility with future majors.
Reviewed by Jarvis 🤖 · Requested by Lautaro Petaccio (<@U025WCHLMN3>) via Slack
| "peerDependencies": { | ||
| "@contentful/rich-text-react-renderer": "^16.0.0", | ||
| "@dcl/hooks": "^1.2.1", | ||
| "@dcl/hooks": ">=1.2.1", |
There was a problem hiding this comment.
[P1] This peer range is broader than the PR's compatibility claim. >=1.2.1 will also accept future @dcl/hooks majors, so npm will not warn consumers if 3.x later changes or removes APIs used by ui2. Please bound the range to the majors validated here, for example ^1.2.1 || ^2.0.0, and apply the same range in package-lock.json.
f909b5e to
25523a8
Compare
The peer was `^1.2.1`, and a caret on a 1.x version excludes 2.x, so @dcl/hooks 2.0.0 could not be resolved by anything reaching this package through decentraland-ui2 regardless of what the consumer declared. Now `^1.2.1 || ^2.0.0`: both majors, nothing beyond. 1.x stays supported, so this is not a breaking change for consumers already on it, and an unbounded range is avoided so a future major that does change the API cannot be absorbed silently. This unblocks the decentraland-crypto-fetch 3 migration. hooks 2.0.0 is the release that widened ITS peer on decentraland-crypto-fetch from `^2.0.1` to `>=2.0.0`; while this range held consumers at 1.x they resolved hooks 1.6.0, which still demands the 2.x signer, and npm could satisfy neither range. builder is carrying an `overrides` entry for exactly that. Admitting both majors is enough to fix it, which is worth stating because it is not obvious: npm does not simply take the lowest version a peer range allows. It resolves the graph, and hooks 1.x cannot coexist with decentraland-crypto-fetch 3, so a consumer on the 3.x signer gets hooks 2 while a consumer on the 2.x signer keeps hooks 1. Verified rather than reasoned: a project declaring decentraland-crypto-fetch ^3.0.0 and this package, with NO overrides entry, resolves to hooks 2.0.0 and crypto-fetch 3.0.0. 2.0.0 changes nothing this package touches. Comparing the published 1.6.0 and 2.0.0 tarballs: the compiled output under `esm/` is byte-identical, no `.d.ts` was added, changed or removed, and the only difference in `package.json` is that one peer range. This package uses `useAdvancedUserAgentData` and the `AdvancedNavigatorUAData` type, both unchanged. The lockfile is regenerated with npm 9.6.7, the version this repository's CI uses. Regenerating with npm 11 drops the optional peer entry for `typescript@5.9.3` nested under @dcl/hooks, and `npm ci` on 9.6.7 then refuses the tree as out of sync -- a build failure unrelated to the range, which is how the first attempt at this PR failed. `npx npm@9.6.7 ci` succeeds here, and build plus the full suite (6 files, 49 tests) pass on the result.
25523a8 to
721ba18
Compare
decentraland-bot
left a comment
There was a problem hiding this comment.
All previous review concerns are resolved. The range is now ^1.2.1 || ^2.0.0 — bounded to known-compatible majors, 1.x still supported (not breaking), no untested future major, lockfile correct. CI is green. LGTM.
The change
A caret on a
1.xversion excludes2.x, so@dcl/hooks@2.0.0couldn't be resolved by anything reaching this package throughdecentraland-ui2— regardless of what the consumer declared.Both majors, nothing beyond. 1.x stays supported, so this isn't breaking for consumers already on it, and an unbounded range is avoided so a future major that does change the API can't be absorbed silently.
Why this unblocks the crypto-fetch 3 migration
hooks 2.0.0 is the release that widened its peer on
decentraland-crypto-fetchfrom^2.0.1to>=2.0.0. While this range held consumers at 1.x, they resolved hooks 1.6.0 — which still demands the 2.x signer — and npm could satisfy neither range. decentraland/builder#3469 is carrying anoverridesentry for exactly that.Admitting both majors is enough, and that's worth stating because it isn't obvious: npm doesn't simply take the lowest version a peer range allows. It resolves the whole graph, and hooks 1.x can't coexist with
decentraland-crypto-fetch3 — so a consumer on the 3.x signer gets hooks 2, while a consumer still on the 2.x signer keeps hooks 1. Both work.Verified, not reasoned
I packed this build and installed it into a fresh project declaring
decentraland-crypto-fetch@^3.0.0with nooverridesentry:Why 2.0.0 is safe to accept
Comparing the published 1.6.0 and 2.0.0 tarballs:
esm/is byte-identical.d.tsadded, changed, or removedpackage.jsondifference is that one peer rangeIt's a semver signal for widening a peer, not an API change. This package imports
useAdvancedUserAgentDataand theAdvancedNavigatorUADatatype — both unchanged.Lockfile
Regenerated with npm 9.6.7, the version this repo's CI uses. Regenerating with npm 11 drops the optional peer entry for
typescript@5.9.3nested under@dcl/hooks, andnpm cion 9.6.7 then refuses the tree as out of sync — which is how the first attempt at this PR failed its build.npx npm@9.6.7 cisucceeds, andnpm run buildplus the full suite (6 files, 49 tests) pass on the result.