refactor(core): collection query executor owns filter/sort/paging with copy-on-output#211
Merged
Conversation
…h copy-on-output Evaluating a `filter` argument previously constructed a whole nested FlatbreadProvider — full config init + schema build + a GraphQL subquery — before sifting, because filters may target resolver-computed fields (_content.html, preknownSchemaFragments). That subquery never received the live contentGraph, so filters could evaluate stale data. Separately, every findById/findMany/all resolver cloneDeep'd its whole collection per call, and resolveSortBy sorted in place on the clone — the "never return shared mutable graph nodes" invariant lived implicitly in a blunt per-call clone. New packages/core/src/query-executor/ module: (Collection snapshot, Relation lookup, query args) → immutable result Records. It owns traversal, filter, sort, paging, ID-normalized lookup, and copy-on-output. Derived-field filters evaluate against a compiled registry: preknown fragment resolvers and config override resolvers run as plain functions over the snapshot; relations traverse via normalized-ID lookup; sift runs over the materialized view. No nested provider, no GraphQL subquery, no stale reads. - findById/findMany/all in schema.ts are now 1–2 line adapters over one executor built per schema generation; per-call cloneDeep retired (ADR-0003 pairs this with incremental reindex). - generators/arguments.ts and resolvers/arguments.ts deleted (shallow single-caller mirrors; failed the deletion test). Arg declarations moved byte-identically to query-executor/graphql-arguments.ts. - One deliberate behavior extension: filters traversing a list relation are now existential (previously non-functional — the old path returned undefined for array traversal). Everything else is test-locked: relational scalar filters, ID normalization, paging slice quirk, DESC-without-sortBy, findMany order/dedupe/error text, validation snapshot messages. Test plan: 17 new AVA executor unit tests (filter incl. derived fields and fragment-parent parity, sort stability + input non-mutation, paging, lookup normalization, result immutability, list-relation existential regression) plus unchanged provider and validation-snapshot suites. Full suite green: pnpm verify (271 AVA + 52 vitest). Co-authored-by: Cursor <[email protected]> Change-Id: If0e0928c6b4a152a502361905bebe5cefcca9332
Collaborator
Author
|
This pull request is part of a Mergify stack:
|
This was referenced Jul 17, 2026
Merged
Merged
Collaborator
Author
|
@Mergifyio queue |
Contributor
Merge Queue Status
This pull request spent 29 minutes 34 seconds in the queue, including 4 minutes 3 seconds running CI. Required conditions to merge
|
Base automatically changed from
stack/tonyketcham/feat/unified-watch-effort-graph/per-mutate-snapshot-decision-lifecycle-module--1b760eb2
to
main
July 18, 2026 09:00
…graph/collection-query-executor-owns-filter-sort-paging--f0e0928c
tonyketcham
deleted the
stack/tonyketcham/feat/unified-watch-effort-graph/collection-query-executor-owns-filter-sort-paging--f0e0928c
branch
July 18, 2026 09:05
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.
Evaluating a
filterargument previously constructed a whole nestedFlatbreadProvider — full config init + schema build + a GraphQL
subquery — before sifting, because filters may target
resolver-computed fields (_content.html, preknownSchemaFragments).
That subquery never received the live contentGraph, so filters could
evaluate stale data. Separately, every findById/findMany/all resolver
cloneDeep'd its whole collection per call, and resolveSortBy sorted in
place on the clone — the "never return shared mutable graph nodes"
invariant lived implicitly in a blunt per-call clone.
New packages/core/src/query-executor/ module: (Collection snapshot,
Relation lookup, query args) → immutable result Records. It owns
traversal, filter, sort, paging, ID-normalized lookup, and
copy-on-output. Derived-field filters evaluate against a compiled
registry: preknown fragment resolvers and config override resolvers
run as plain functions over the snapshot; relations traverse via
normalized-ID lookup; sift runs over the materialized view. No nested
provider, no GraphQL subquery, no stale reads.
one executor built per schema generation; per-call cloneDeep retired
(ADR-0003 pairs this with incremental reindex).
single-caller mirrors; failed the deletion test). Arg declarations
moved byte-identically to query-executor/graphql-arguments.ts.
relation are now existential (previously non-functional — the old
path returned undefined for array traversal). Everything else is
test-locked: relational scalar filters, ID normalization, paging
slice quirk, DESC-without-sortBy, findMany order/dedupe/error text,
validation snapshot messages.
Test plan: 17 new AVA executor unit tests (filter incl. derived
fields and fragment-parent parity, sort stability + input
non-mutation, paging, lookup normalization, result immutability,
list-relation existential regression) plus unchanged provider and
validation-snapshot suites. Full suite green: pnpm verify (271 AVA +
52 vitest).
Co-authored-by: Cursor [email protected]
Depends-On: #210