Repository navigation
fix(cache): clone cached issues to stop issue paths from accumulating - #1620
fabian-hiller merged 2 commits into
Conversation
`_cloneDataset` in `library/src/utils/_cloneDataset/_cloneDataset.ts` copied
the `issues` array of a cached dataset but kept the issue objects themselves,
so `cache` and `cacheAsync` handed the same issue object back on every cache
hit. Parent schemas mutate the issues they receive, for example `object` in
`library/src/schemas/object/object.ts` runs `issue.path.unshift(pathItem)` or
`issue.path = [pathItem]`, so each hit added another path item to the cached
issue. Parsing `object({ key: cache(pipe(string(), minLength(3))) })` three
times produced the dot paths `key`, `key.key` and `key.key.key`, and the keys
of `flatten` grew with them.
`_cloneDataset` now clones each issue and its `path` array, so the mutations
of a parent schema or of `forward` apply to the returned copy instead of the
cached one.
7309a82 to
2a5b68b
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. Walkthrough
Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to Cached validation issues and their path arrays are cloned to prevent paths accumulating across repeated parses. No current merge-blocking risk is identified. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
yslpn
left a comment
There was a problem hiding this comment.
Thanks, good fix. I have no issues with it. LGTM.
|
Thank you! |
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [valibot](https://valibot.dev) ([source](https://github.com/open-circle/valibot)) | [`1.4.2` → `1.5.0`](https://renovatebot.com/diffs/npm/valibot/1.4.2/1.5.0) |  |  | --- ### Release Notes <details> <summary>open-circle/valibot (valibot)</summary> ### [`v1.5.0`](https://github.com/open-circle/valibot/releases/tag/v1.5.0) [Compare Source](open-circle/valibot@v1.4.2...v1.5.0) Many thanks to [@​tats-u](https://github.com/tats-u), [@​idleberg](https://github.com/idleberg), [@​yslpn](https://github.com/yslpn), [@​francisjohnjohnston-web](https://github.com/francisjohnjohnston-web), [@​MaxFreedomPollard](https://github.com/MaxFreedomPollard), [@​mahirhir](https://github.com/mahirhir), [@​ItzXynx](https://github.com/ItzXynx), [@​LeSingh1](https://github.com/LeSingh1), [@​maxtaran2010](https://github.com/maxtaran2010), [@​ysknsid25](https://github.com/ysknsid25), [@​cyyynthia](https://github.com/cyyynthia), [@​spokodev](https://github.com/spokodev) and [@​sanjibani](https://github.com/sanjibani) for contributing to this release. - Add `codePoints`, `maxCodePoints`, `minCodePoints` and `notCodePoints` validation actions to validate the number of Unicode code points (pull request [#​888](open-circle/valibot#888)) - Add `ksuid` validation action to validate KSUIDs (pull request [#​1370](open-circle/valibot#1370)) - Change Standard Schema properties to use eager initialization for faster schema construction and replace internal `_getStandardProps` utility with `_standardSchema` (pull request [#​1534](open-circle/valibot#1534)) - Change `url` action to use `URL.canParse` when available to avoid constructing URL objects (pull request [#​1608](open-circle/valibot#1608)) - Fix `stringifyJson` action to preserve the dataset value when `JSON.stringify` returns `undefined` (pull request [#​1476](open-circle/valibot#1476)) - Fix `literal` schema and `value`, `values`, `notValue` and `notValues` actions to treat `NaN` as equal to itself (pull request [#​1573](open-circle/valibot#1573)) - Fix `intersect` schema to merge matching `NaN` values and invalid dates (pull request [#​1573](open-circle/valibot#1573)) - Fix `cache` and `cacheAsync` methods to clone the issues of a cached dataset, preventing parent schemas from adding their path item to the same issue on every cache hit (pull request [#​1620](open-circle/valibot#1620)) - Fix `strictObject`, `looseObject`, `objectWithRest` and their async variants to correctly handle unknown input keys that collide with `Object.prototype` members (pull request [#​1523](open-circle/valibot#1523)) - Fix `intersect` and `intersectAsync` schemas to ignore inherited properties when merging objects and preserve own properties without invoking inherited setters or changing the output prototype (pull request [#​1621](open-circle/valibot#1621)) - Fix `ulid` action to reject ULIDs that exceed the maximum 128-bit value (pull request [#​1498](open-circle/valibot#1498)) - Fix `email` action to reject non-ASCII characters accepted by Unicode case folding (pull request [#​1075](open-circle/valibot#1075)) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC44Mi4xIiwidXBkYXRlZEluVmVyIjoiNDQuODIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
A schema wrapped in
cachethat sits inside a parent schema grows an extra path item on its issues on every cache hit, so the reported path is wrong from the second parse onwards.v.flattenis affected the same way, which is how this shows up in form code:{ nested: { key: [...] } }on the first parse, then{ nested: { 'key.key': [...] } }, then{ nested: { 'key.key.key': [...] } }.Cause
_cloneDatasetinlibrary/src/utils/_cloneDataset/_cloneDataset.tsclones theissuesarray of the cached dataset but keeps the issue objects inside it:Issues are mutable, and every parent schema mutates the ones it receives. For example
objectinlibrary/src/schemas/object/object.tsdoesissue.path.unshift(pathItem)when a path already exists andissue.path = [pathItem]when it does not, andforwardinlibrary/src/methods/forward/forward.tspushes onto the same array. BecausecacheandcacheAsyncreturn the very same issue object on every hit, each parse appends its path item to the issue that is still sitting in the cache, and the path keeps growing. Cloning the array only prevents the parent from pushing further issues into the cached array, not from mutating the issues themselves.The
patharray needs the same treatment as the issue object. When the cached schema already produces a path of its own,unshiftmutates the array that the cached issue still points at.Fix
_cloneDatasetnow clones each issue and itspatharray, so a parent schema andforwardmutate the returned copy instead of the cached one.valueis still copied by reference, and the subissuesof an issue are untouched because no schema mutates those.Tests
library/src/utils/_cloneDataset/_cloneDataset.test.tsnow asserts that the issues and theirpatharrays are copies rather than the originals, with the path items themselves still shared by reference.library/src/methods/cache/cache.test.tsandlibrary/src/methods/cache/cacheAsync.test.tseach gain a regression test that parses the schema above three times and expects the dot path to staykey. All five assertions fail onmainand pass with this change.Verification
pnpm testinlibrary: 530 files, 4609 tests passed, no type errors.pnpm lintinlibrary(eslint,tsc --noEmit,deno check ./src/index.ts) andpnpm format.checkboth pass.Summary by CodeRabbit
Bug Fixes
Documentation