(query: QueryExpression<T>, object: T)
| 82 | } |
| 83 | |
| 84 | export function objectMatchesQuery<T extends object>(query: QueryExpression<T>, object: T) { |
| 85 | for (const [key, matcher] of Object.entries(query)) { |
| 86 | const value = object[key as keyof T] |
| 87 | |
| 88 | // if you add matching logic here, make sure you also update executeQuery, |
| 89 | // where initial data is pulled out of the indexes, since that requires different |
| 90 | // matching logic |
| 91 | if (isQueryValueMatcher(matcher)) { |
| 92 | if ('eq' in matcher && value !== matcher.eq) return false |
| 93 | // undefined values must not match neq: the indexes executeQuery reads only |
| 94 | // track defined values, and the two matching strategies have to agree |
| 95 | if ('neq' in matcher && (value === matcher.neq || value === undefined)) return false |
| 96 | if ('gt' in matcher && (typeof value !== 'number' || value <= matcher.gt)) return false |
| 97 | continue |
| 98 | } |
| 99 | |
| 100 | // It's a nested query |
| 101 | if (typeof value !== 'object' || value === null) return false |
| 102 | if (!objectMatchesQuery(matcher as QueryExpression<any>, value as any)) { |
| 103 | return false |
| 104 | } |
| 105 | } |
| 106 | return true |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Executes a query against the store using reactive indexes to efficiently find matching record IDs. |
no test coverage detected
searching dependent graphs…