fix(bindx): resolve auto-generated has-many alias on accessor reads (#53)#54
Merged
Merged
Conversation
) A has-many relation selected with params (orderBy/filter/limit/offset) is stored under an auto-generated alias (e.g. `tags_<hash>`), but the read path looked it up under the plain field name and came back empty. Two gaps: - `useEntity`/`useEntityList` never threaded the selection into the root `EntityHandle`, so `this.selection` was undefined and no alias could be resolved. - `EntityHandle.fields` passed `undefined` as the alias to `hasMany()`, reading `data['tags']` instead of `data['tags_<hash>']`. Fix: thread `selectionMeta` into the root handle in both hooks, and add `EntityHandle.resolveSelectionField()` which recovers the stored alias by matching on `fieldName` for array relations (scalar/has-one explicit aliases still report unfetched when read by their original name). The resolved alias + nested selection are threaded into `hasMany()`. This also makes the hooks selection-aware (UnfetchedFieldError), matching the existing `<Entity>` JSX path. Adds regression tests for both the list- and single-entity accessor paths, asserting orderBy is honored on read. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EAKx7JbV7Z7EVXofqRgwop
f802310 to
1cad4db
Compare
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.
Closes #53.
Problem
A has-many relation selected with params (
orderBy/filter/limit/offset) reads back as an empty list on the resulting accessor —list.items[i].<relation>.itemsis always[]. Scalar siblings load fine; dropping the params makes the relation populate. The data is fetched correctly; it's lost between store and accessor.Root cause
A has-many with params gets an auto-generated alias (
generateHasManyAlias→tags_<hash>), so the fetched rows land in the entity snapshot underdata['tags_<hash>']. The read path had two gaps:useEntity/useEntityListnever threaded the selection into the rootEntityHandle, sothis.selectionwasundefinedand no alias could be resolved.EntityHandle.fieldspassedundefinedas the alias tohasMany(), soHasManyListHandlelooked underdata['tags'](empty) instead ofdata['tags_<hash>'].The consumer reads the relation by its real field name (
tags) — it can't know the hash alias — so the read side must map field name → stored alias.Fix
EntityHandle— newresolveSelectionField(name): direct lookup first, then for array relations falls back to matching onfieldName, recovering the auto-generated alias. The resolvedalias+nestedselection are threaded intohasMany(). The fallback is restricted to has-many so explicit scalar/has-one aliases still report unfetched when read by their original name.useEntity/useEntityList— passselectionMetato the rootEntityHandle(+ dep arrays).This also makes the hooks selection-aware (
UnfetchedFieldError), consistent with the already-validating<Entity>JSX path — it completes the existing selection design rather than changing it.Tests
tests/react/hooks/useEntityList/nestedHasManyOrderBy.test.tsx— the reported repro (list path).tests/react/hooks/useEntity/nestedHasManyOrderBy.test.tsx— companion single-entity path, also assertingorderByis honored on read.Verification
tests/browser/*(need the live playground) andFormHasManyRelationScope › tracks dirty state(fails identically on cleanmain, verified in a worktree). Zero new failures.packages/example/App.tsxerror is a pre-existing duplicate@contember/graphql-clientinstall).🤖 Generated with Claude Code