@spooky-sync/query-builder 0.0.1-canary.64 → 0.0.1-canary.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +63 -0
- package/package.json +1 -1
package/AGENTS.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# `@spooky-sync/query-builder` — agent guide
|
|
2
|
+
|
|
3
|
+
## What this package is
|
|
4
|
+
|
|
5
|
+
The type-safe SurrealQL query builder used by `@spooky-sync/core` and `@spooky-sync/client-solid`. It encodes the user's `.surql` schema as a TypeScript type and rejects invalid table names, fields, and relationship traversals at compile time. It also serializes builder chains into SurQL strings for execution.
|
|
6
|
+
|
|
7
|
+
You usually don't import this directly — `db.query('thread')` returns a `QueryBuilder` and the package's types are re-exported from `@spooky-sync/client-solid`. Reach for it when writing generic helpers, type utilities, or non-Solid bindings.
|
|
8
|
+
|
|
9
|
+
## DSL overview
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
db.query('thread') // QueryBuilder<Schema, 'thread', ...>
|
|
13
|
+
.where({ active: true }) // partial-equality filter
|
|
14
|
+
.select('id', 'title', 'created_at') // omit for SELECT *
|
|
15
|
+
.related('author') // follow a record-link relationship
|
|
16
|
+
.related('comments', { orderBy: { created_at: 'desc' } })
|
|
17
|
+
.orderBy('created_at', 'desc')
|
|
18
|
+
.limit(20)
|
|
19
|
+
.offset(0)
|
|
20
|
+
.build(); // → FinalQuery (call .run() or hand to useQuery)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`build()` returns a `FinalQuery`. `useQuery(() => ...build())` calls `.run()` for you and tracks the factory reactively. Standalone consumers call `.run()` themselves; the executor returns whatever the binding configures (in client-solid: a `Sp00kyQueryResultPromise`).
|
|
24
|
+
|
|
25
|
+
## Key exports (`src/index.ts`)
|
|
26
|
+
|
|
27
|
+
- **Builders**: `QueryBuilder`, `InnerQuery`, `FinalQuery`, `Executor`, `buildQueryFromOptions`, `cyrb53` (hash function used to dedupe queries).
|
|
28
|
+
- **Schema type helpers** (load-bearing — these power the type-safety in every consumer):
|
|
29
|
+
- `SchemaStructure` — the shape of the generated `schema` object.
|
|
30
|
+
- `TableNames<S>` — union of valid table name literals.
|
|
31
|
+
- `GetTable<S, T>` / `TableModel<T>` — row type for table `T`.
|
|
32
|
+
- `TableRelationships<S, T>` / `RelationshipFieldsFromSchema<S, T>` — the typed relationship surface.
|
|
33
|
+
- `BackendNames<S>` / `BackendRoutes<S, B>` / `RoutePayload<S, B, R>` — for `db.run(...)`.
|
|
34
|
+
- `BucketNames<S>` / `BucketConfig<S, B>` / `BucketDefinitionSchema`.
|
|
35
|
+
- `AccessDefinition`, `TypeNameToTypeMap`.
|
|
36
|
+
- **Query result types**: `QueryResult`, `RelatedFieldsMap`, `BuildResultModelOne`, `BuildResultModelMany`, `WithRelated`, `GetCardinality`.
|
|
37
|
+
- **Modifier helpers**: `QueryModifier`, `QueryModifierBuilder`, `SchemaAwareQueryModifier`, `SchemaAwareQueryModifierBuilder`.
|
|
38
|
+
|
|
39
|
+
## Builder method surface
|
|
40
|
+
|
|
41
|
+
- `.where(partial)` — equality filters; `partial` is `Partial<TableModel<...>>`.
|
|
42
|
+
- `.select(...fields)` — narrow returned columns. Calling twice throws.
|
|
43
|
+
- `.orderBy(field, 'asc' | 'desc')`.
|
|
44
|
+
- `.limit(n)`, `.offset(n)`.
|
|
45
|
+
- `.related(field, modifier?)` — pull in a related record (or array) by field name. `modifier` is a builder callback for nested filters / selects on the related table. Three signatures: `(field)`, `(field, modifier)`, `(field, cardinality, modifier)`.
|
|
46
|
+
- `.build()` — produces a `FinalQuery`.
|
|
47
|
+
- `FinalQuery.run()` — executes via the configured executor.
|
|
48
|
+
- `FinalQuery.selectLive()` — returns the LIVE SELECT `QueryInfo` for subscriptions.
|
|
49
|
+
- `FinalQuery.buildUpdateQuery(patches)` / `buildDeleteQuery()` — used by `db.update` / `db.delete` internally.
|
|
50
|
+
|
|
51
|
+
## Common gotchas
|
|
52
|
+
|
|
53
|
+
- **`select()` is exclusive.** Either select specific fields or omit the call for `*` — don't chain `.select(...)` more than once.
|
|
54
|
+
- **Relationships must exist in the schema.** `related('foo')` is a type error if `foo` isn't a relationship column. Run `spky generate` after editing the `.surql` to refresh the type.
|
|
55
|
+
- **`where` is equality-only.** For `>`, `<`, `IN`, free-form predicates, use `db.useRemote(s => s.query(...))` and write SurQL directly.
|
|
56
|
+
- **Record-ID strings are auto-parsed.** Passing `"thread:abc"` into a `where` matches a `RecordId('thread', 'abc')`. Don't double-wrap.
|
|
57
|
+
- **The serialized SurQL is hashable.** `cyrb53` over the query string drives cache keys — two builders that produce identical SurQL share a cache entry.
|
|
58
|
+
|
|
59
|
+
## Pointers
|
|
60
|
+
|
|
61
|
+
- Sync engine (executor implementation): `node_modules/@spooky-sync/core/AGENTS.md`
|
|
62
|
+
- Reactive consumption: `node_modules/@spooky-sync/client-solid/AGENTS.md`
|
|
63
|
+
- Schema authoring: `node_modules/@spooky-sync/cli/AGENTS.md`
|
package/package.json
CHANGED