MCPcopy Index your code
hub / github.com/TanStack/db / buildCursor

Function buildCursor

packages/db/src/utils/cursor.ts:21–78  ·  view source on GitHub ↗
(
  orderBy: OrderBy,
  values: Array<unknown>,
)

Source from the content-addressed store, hash-verified

19 * @returns A filter expression for rows after the cursor position, or undefined if empty
20 */
21export function buildCursor(
22 orderBy: OrderBy,
23 values: Array<unknown>,
24): BasicExpression<boolean> | undefined {
25 if (values.length === 0 || orderBy.length === 0) {
26 return undefined
27 }
28
29 // For single column, just use simple gt/lt
30 if (orderBy.length === 1) {
31 const { expression, compareOptions } = orderBy[0]!
32 const operator = compareOptions.direction === `asc` ? gt : lt
33 return operator(expression, new Value(values[0]))
34 }
35
36 // For multi-column, build the composite cursor:
37 // or(
38 // gt(col1, v1),
39 // and(eq(col1, v1), gt(col2, v2)),
40 // and(eq(col1, v1), eq(col2, v2), gt(col3, v3)),
41 // ...
42 // )
43 const clauses: Array<BasicExpression<boolean>> = []
44
45 for (let i = 0; i < orderBy.length && i < values.length; i++) {
46 const clause = orderBy[i]!
47 const value = values[i]
48
49 // Build equality conditions for all previous columns
50 const eqConditions: Array<BasicExpression<boolean>> = []
51 for (let j = 0; j < i; j++) {
52 const prevClause = orderBy[j]!
53 const prevValue = values[j]
54 eqConditions.push(eq(prevClause.expression, new Value(prevValue)))
55 }
56
57 // Add the comparison for the current column (respecting direction)
58 const operator = clause.compareOptions.direction === `asc` ? gt : lt
59 const comparison = operator(clause.expression, new Value(value))
60
61 if (eqConditions.length === 0) {
62 // First column: just the comparison
63 clauses.push(comparison)
64 } else {
65 // Subsequent columns: and(eq(prev...), comparison)
66 // We need to spread into and() which expects at least 2 args
67 const allConditions = [...eqConditions, comparison]
68 clauses.push(allConditions.reduce((acc, cond) => and(acc, cond)))
69 }
70 }
71
72 // Combine all clauses with OR
73 if (clauses.length === 1) {
74 return clauses[0]!
75 }
76 // Use reduce to combine with or() which expects exactly 2 args
77 return clauses.reduce((acc, clause) => or(acc, clause))
78}

Callers 3

cursor.test.tsFile · 0.85

Calls 3

eqFunction · 0.50
andFunction · 0.50
orFunction · 0.50

Tested by

no test coverage detected