Querying content
Everything below assumes you ran GemSync and have a
gemRouter.ts in your repo. The client is a plain tRPC client, so each
collection under gem.tables exposes typed procedures: find, all and
where for reads, create, update and destroy for writes.
import { createGemClient } from "@gemzero0/sdk-core";import type { GemRouter } from "./gemRouter";
const gem = createGemClient<GemRouter>({ url: process.env.GEM_URL!, key: process.env.GEM_KEY!,});// One document by id (null when it doesn't exist)const post = await gem.tables.posts.find.query({ id: "20240119104533_1705657533",});
// A page of documentsconst { results } = await gem.tables.posts.all.query({ limit: 10 });
// Filteredconst { results: published } = await gem.tables.posts.where.query({ query: { published: { $eq: true } }, limit: 20,});all and where accept limit, cursor and sort (an array of
{ field: "asc" | "desc" } entries). where takes a query built from these
operators:
| Operators | Meaning |
|---|---|
$eq, $ne | Equals / not equals |
$lt, $lte, $gt, $gte | Comparisons |
$in, $nin | Value in / not in a list |
$exists | Field present or absent |
$regex | Match a regular expression |
$size | Array length |
$and, $or | Group conditions |
Writes
Section titled “Writes”Documents carry two meta fields: _uid (the id) and _ver (the version).
Updates and deletes require both. A stale _ver is rejected, so a concurrent
edit fails loudly instead of silently overwriting; fetch before you write.
// Createconst { data: created } = await gem.tables.posts.create.mutate({ title: "Hello", published: false,});
// Update: fetch, change, send back with _uid and _verconst post = await gem.tables.posts.find.query({ id });if (post) { await gem.tables.posts.update.mutate({ ...post, title: "New title" });}
// Deleteawait gem.tables.posts.destroy.mutate({ _uid: post._uid, _ver: post._ver,});Writes run the same validations as the dashboard. Collections can be read-only; write procedures are only generated where the schema allows writing.
Query options
Section titled “Query options”Reads accept two options alongside their parameters:
without_links: trueskips expandinglinkfields into full documents (pair it withgemsync --without-linksso the types match).with_base64: trueincludes file contents inline forfilefields instead of metadata only.
React and Next.js
Section titled “React and Next.js”@gemzero0/sdk-react wraps the same router in React Query hooks:
import { createGemProvider } from "@gemzero0/sdk-react";import type { GemRouter } from "./gemRouter";
const { GemProvider, Gem } = createGemProvider<GemRouter>();
// In your root:// <GemProvider gemUrl={GEM_URL} gemKey={GEM_KEY}>...</GemProvider>
// In a component:const { data } = Gem.tables.posts.all.useQuery({ limit: 10 });@gemzero0/sdk-next provides the same for Next.js apps.