fix: land the deferred @Joined resolution in main (01B) - #22
Merged
Conversation
* fix: resolve deferred joined fields from the List stream itself Query.List deferred the display-only joined groups and returned their names as a third tuple element for the list route to materialize on the page. Consumers that destructure [query, total] alone (the cms buildFilteredQuery among them) lost that set, so the deferred @joined fields never resolved: lists came back without the joined columns and search filters on them matched nothing. Wrap the returned stream instead: it materializes the deferred groups itself as soon as an operation can observe them, keeps the lookups after slice/nth so they still only run on the returned page, skips them for bare count() calls and for field aggregates on non-joined fields (left-join lookups change neither the row count nor other fields, and a joined-field aggregate only materializes its own group), and attaches changes() to the raw stream since change feeds cannot carry the lookups. The third tuple element is now empty by default; the list route opts back into the raw stream with exposeDeferredJoined to keep restricting the page lookups to the plucked fields, and a db-less call also returns the raw stream with the unresolved names since no lookup can be built without a database. * docs: document deferred joined resolution on lists * fix: keep nth() joins on the stream form and document the paging caveat Routing nth() through the datum form of Joined left the temporary __joined_orig_* key on the returned row: only the stream form drops it, since neither Datum nor ValueProxy exposes without(). Slice the single row first and join the stream instead, which also keeps the lookup on that row alone. Also correct the docs: the page-only benefit holds while paging is the first operation the caller applies. A filter, a sort or the lookup Query.Foreign stages for a @foreign field materializes the groups over the whole matched set (still outside the count pipeline); callers that need them strictly on the page have exposeDeferredJoined.
Upd4ting
approved these changes
Aug 5, 2026
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.
Consolidates
tmp/fixes-batchintomain: the@Joinedregression fix from #21 (merged 2026-07-28) —Query.Listnow resolves its own deferred joined fields, so consumers (the cms members list among them) get populated results again without any change on their side.The branch was never consolidated, so
main(and the v0.1.7 release currently on npm) still ships the regression. This must land before the npm publish: publishing from today's main would ship without the fix. Publish plan after merge: release@antelopejs/interface-data-api. (Republish the shell— stale instruction: nothing consumes the shell module anymore, every consumer imports@antelopejs/data-apiinterface-data-apidirectly with a range that picks the new version up on install.)Greptile Summary
The PR makes
Query.Listreturn a self-resolving stream for deferred@Joinedfields while preserving page-scoped lookups and count efficiency.Confidence Score: 5/5
The PR appears safe to merge with no concrete blocking or independently actionable non-blocking issue identified.
The deferred join wrapper preserves joined-field visibility across the tested stream operations while keeping lookups out of count pipelines and after page boundaries where intended.
Important Files Changed
Query.Listoption for exposing unresolved joined fields.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Query.List] --> B{Joined field needed by filter or sort?} B -->|Yes| C[Materialize before count or sort] B -->|No| D{Expose deferred fields?} D -->|Yes| E[Return raw stream and deferred field set] D -->|No| F[Return DeferredJoinedStream] F --> G{First operation} G -->|slice or nth| H[Page first, then resolve joins] G -->|count or eligible aggregate| I[Use raw pipeline] G -->|other row-observing operation| J[Resolve joins before operation]Reviews (1): Last reviewed commit: "fix: resolve deferred joined fields from..." | Re-trigger Greptile