AI agents: fetch the documentation index at llms.txt. Markdown versions are available by appending .md to any page URL, including this page's markdown.
Query API
Filter, sort, and paginate synced models with composable query operators.
Filter, sort, and paginate models from the identity map. All queries run in-memory against locally cached data.
QueryOptions
interface QueryOptions<T> {
where?: (item: T) => boolean;
orderBy?: (a: T, b: T) => number;
limit?: number;
offset?: number;
includeArchived?: boolean;
}| Option | Type | Default | Description |
|---|---|---|---|
where | (item: T) => boolean | - | Filter predicate. Only items returning true are included. |
orderBy | (a: T, b: T) => number | - | Sort comparator (same as Array.sort). |
limit | number | - | Maximum results to return. |
offset | number | - | Number of results to skip. |
includeArchived | boolean | false | Include soft-deleted items (those with archivedAt). |
QueryResult
interface QueryResult<T> {
data: T[];
hasMore: boolean;
totalCount?: number;
}| Field | Description |
|---|---|
data | The filtered, sorted, paginated results. |
hasMore | true if more results exist beyond the limit. |
totalCount | Total count of matching items before pagination. |
Basic usage
import { createSyncClient } from "@stratasync/client";
// Simple filter
const result = await client.query<Task>("Task", {
where: (task) => task.projectId === "proj-123",
});
// With sorting and pagination
const result = await client.query<Task>("Task", {
where: (task) => task.status === "todo",
orderBy: (a, b) => b.priority - a.priority,
limit: 20,
offset: 0,
});
// Include archived
const result = await client.query<Task>("Task", {
includeArchived: true,
});Filter operators
Composable filter functions that return predicates for where.
eq: equality
Matches items where a field equals a value.
import { eq } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: eq("status", "todo"),
});Signature: eq<T, K extends keyof T>(field: K, value: T[K]): (item: T) => boolean
neq: not equal
Matches items where a field doesn't equal a value.
import { neq } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: neq("status", "done"),
});Signature: neq<T, K extends keyof T>(field: K, value: T[K]): (item: T) => boolean
Comparison operators
Work with numeric fields. Return false for non-numeric values.
gt: greater than
import { gt } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: gt("priority", 5),
});Signature: gt<T, K extends keyof T>(field: K, value: T[K]): (item: T) => boolean
lt: less than
import { lt } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: lt("priority", 3),
});Signature: lt<T, K extends keyof T>(field: K, value: T[K]): (item: T) => boolean
isIn: set membership
Matches items where a field's value is in the given array. Uses a Set for O(1) lookups.
import { isIn } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: isIn("status", ["todo", "in_progress"]),
});Signature: isIn<T, K extends keyof T>(field: K, values: T[K][]): (item: T) => boolean
contains: substring match
Checks if a string field includes a substring.
import { contains } from "@stratasync/client";
// Case-insensitive (default)
const result = await client.query<Task>("Task", {
where: contains("title", "bug"),
});
// Case-sensitive
const result = await client.query<Task>("Task", {
where: contains("title", "Bug", true),
});Signature: contains<T>(field: keyof T, substring: string, caseSensitive?: boolean): (item: T) => boolean
matches: regex match
Tests a string field against a regular expression.
import { matches } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: matches("title", /^URGENT:/i),
});Signature: matches<T>(field: keyof T, pattern: RegExp): (item: T) => boolean
Logical combinators
Build compound predicates with and, or, and not.
and: combine with AND
import { and, eq, gt } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: and(eq("status", "todo"), gt("priority", 3)),
});Signature: and<T>(...filters: Array<(item: T) => boolean>): (item: T) => boolean
or: combine with OR
import { or, eq } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: or(eq("status", "todo"), eq("status", "in_progress")),
});Signature: or<T>(...filters: Array<(item: T) => boolean>): (item: T) => boolean
not: negate a filter
import { not, eq } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: not(eq("status", "done")),
});Signature: not<T>(filter: (item: T) => boolean): (item: T) => boolean
Composing complex queries
Nest combinators freely:
import { and, or, eq, gt, contains, not } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: and(
eq("projectId", "proj-123"),
not(eq("status", "done")),
or(gt("priority", 5), contains("title", "urgent"))
),
orderBy: (a, b) => b.priority - a.priority,
limit: 50,
});Sort utilities
sortBy
Comparator for a single field. Supports string, number, and Date. Sorts null/undefined last.
import { sortBy } from "@stratasync/client";
const result = await client.query<Task>("Task", {
orderBy: sortBy("priority", "desc"),
});Signature: sortBy<T>(field: keyof T, direction?: "asc" | "desc"): (a: T, b: T) => number
combineSorts
Chains comparators. First defines the primary sort; subsequent ones break ties.
import { sortBy, combineSorts } from "@stratasync/client";
const result = await client.query<Task>("Task", {
orderBy: combineSorts(sortBy("priority", "desc"), sortBy("title", "asc")),
});Signature: combineSorts<T>(...sorts: Array<(a: T, b: T) => number>): (a: T, b: T) => number
Archived items
Queries exclude items with archivedAt by default. Set includeArchived: true to include them.
const result = await client.query<Task>("Task", {
includeArchived: true,
});To query only archived items, combine includeArchived with a where predicate:
import { and } from "@stratasync/client";
const result = await client.query<Task>("Task", {
where: (task) => Boolean(task.archivedAt),
includeArchived: true,
});