Query Data
Querying data in Sp00ky is designed to be intuitive and reactive. The system handles the entire lifecycle of a query, from initialization to registration and liveness updates, ensuring your UI is always consistent with the database state.
Query Lifecycle
- Initialization: When a component requests data, Sp00ky checks if a live query for that data already exists.
- Registration: If not, it registers a new query with the sync engine.
- Liveness: The query remains “live” as long as there are active subscribers. Sp00ky automatically manages subscriptions and unsubscription to optimize performance.
Fluent Query API
The db.query() method provides a fluent interface to construct queries. It is fully type-safe based on your schema.
Relationships
Sp00ky makes fetching related data incredibly simple with the .related() method. It automatically handles the underlying graph traversals or joins.
Unified Query Syntax
Whether you are fetching a simple 1:1 link, a 1:N collection, or traversing a complex N:M graph, the syntax remains exactly the same. Sp00ky uses your schema definition to determine how to fetch the data.
Magic behind the scenes: You don’t need to manually specify graph paths (e.g., ->liked->post) or join conditions. Sp00ky inspects your schema.surql to understand that liked is a relation table connecting users to posts, and generates the correct query automatically.
Type Safety
One of Sp00ky’s strongest features is its end-to-end type safety.
When you use .related(), the return type of your query is automatically adjusted.
- Without
.related(): The field is astring(Record ID). - With
.related(): The field becomes the full related object with selected fields.
This ensures you can never accidentally access a property on a relation that hasn’t been fetched. TypeScript will catch the error at compile time.
Using Hooks (SolidJS Example)
For reactive applications, Sp00ky provides hooks that automatically update your component when the data changes.