Skip to content

canonicalRowFilter

canonicalRowFilter(props): ConvexQueryFilterFn | undefined

Defined in: packages/core/src/versions/statusQueryConstraint.ts:69

Filter predicate that excludes a LINKED draft row from a drafts: true read — a row with vex_status === "draft" AND a vex_publishedId pointing at another row — while keeping that row’s published counterpart and any draft-ONLY row (vex_publishedId unset, never published). Scoped to the admin list’s draft-aware read merge path (the draft-pair pagination fix): find/search page over these “canonical” rows — one per logical document — and mergeDraftCounterparts (collections/query/mergeDraftCounterparts.ts) attaches each linked draft’s own fields back in per page, instead of returning the draft row as a second, separate row for the client to pair up itself (the former client-side collapseVersionedPairs approach — removed, unused once this server-side merge replaced it — which could split a pair across the client’s own reveal window and permanently miscount totalDocs).

Never an index range: the predicate it keeps is an OR (“published, OR a draft with no publishedId”) — no single Convex index range expresses that — so this always folds into .filter(), the same fallback shape composeStatusQueryConstraint’s own .filter() branches already use. Both fields it reads are already loaded off every row the query’s index/filter scan visits, so this adds no extra read.

Input props.

string

The collection slug being queried.

VexConfig

The resolved VexConfig.

boolean

The caller’s EFFECTIVE drafts flag (find’s wantsDrafts, or search’s own args.drafts — see each call site).

ConvexQueryFilterFn | undefined

A filter fn to AND in alongside the caller’s other filters, or undefined when drafts isn’t true or collection isn’t versioned — nothing to narrow, so an ordinary (non-admin-list) read pays nothing extra.