Skip to content

Conversation

@vrn21
Copy link

@vrn21 vrn21 commented Dec 18, 2025

Description

Embeddable SDK (helix-lib)

Adds helix-lib - an embeddable SDK for using HelixDB without a server.

What It Does

Compile .hx schemas/queries to Rust at build time, execute them in-process.

// build.rs
fn main() {
    helix_lib::build::compile_queries_default().expect("Failed to compile");
}

// main.rs
mod queries;
use helix_lib::{HelixDB, ResponseExt};

let config = queries::config()?;
let db = HelixDB::new("./data", config)?;
let users: UsersResponse = db.execute("GetUsers", json!({}))?.deserialize()?;

Changes

New Package: helix-lib/

  • src/lib.rs - HelixDB struct, execute() API
  • src/errors.rs - Error types
  • src/build.rs - Build-time compiler
  • examples/simple/ - Working example
  • README.md - Docs

API

pub fn execute<T: Serialize>(&self, query_name: &str, params: T) -> Result<Response>

Response helpers via ResponseExt trait:

  • deserialize<T>() - Type-safe deserialization
  • json() - Dynamic JSON access
  • get_field<T>(field) - Field extraction

Testing

✅ Example builds and runs
✅ Handler registration works
✅ Type-safe deserialization works
✅ No breaking changes

See helix-lib/examples/simple/ for fully-fledged example.

Related Issues

Closes #104

Checklist when merging to main

  • No compiler warnings (if applicable)
  • Code is formatted with rustfmt
  • No useless or dead code (if applicable)
  • Code is easy to understand
  • Doc comments are used for all functions, enums, structs, and fields (where appropriate)
  • All tests pass
  • Performance has not regressed (assuming change was not to fix a bug)
  • Version number has been updated in helix-cli/Cargo.toml and helixdb/Cargo.toml

Additional Notes

Greptile Summary

Adds helix-lib, an embeddable SDK that compiles .hx schemas/queries to Rust at build time, enabling in-process database operations without a server.

Key Changes:

  • New helix-lib package with HelixDB struct and execute() API for query execution
  • Build-time compiler (build.rs) that parses .hx files and generates queries.rs with handler registrations
  • ResponseExt trait providing deserialize(), json(), and get_field() helpers for type-safe response handling
  • One examples (simple) demonstrating user creation and retrieval workflows
  • Generator improvements to support embeddable use case with proper imports and documentation

Issues Found:

  • Invalid Rust edition "2024" in helix-lib/Cargo.toml (should be "2021")
  • Type mismatches in documentation: queries::config() returns Option<Config> but examples use ? operator expecting Result
  • Doc example suggests .unwrap_or_default() but Config doesn't implement Default

Important Files Changed

Filename Overview
helix-lib/src/lib.rs Core SDK implementation with HelixDB struct, execute() API, and ResponseExt trait
helix-lib/src/build.rs Build-time compiler for .hx files with recursive file collection and code generation
helix-lib/Cargo.toml Package manifest using edition = "2024" (non-standard)
helix-lib/README.md Comprehensive documentation with quick start guide and API examples

Sequence Diagram

sequenceDiagram
    participant User as User Code
    participant Build as build.rs
    participant Compiler as HelixC Compiler
    participant Gen as queries.rs (generated)
    participant DB as HelixDB
    participant Storage as HelixGraphStorage
    participant Handler as Query Handler

    Note over User,Gen: Build Time
    User->>Build: cargo build
    Build->>Compiler: compile_queries_default()
    Compiler->>Compiler: parse .hx files
    Compiler->>Compiler: analyze schema
    Compiler->>Gen: generate queries.rs
    Gen->>Gen: register handlers via #[handler]
    
    Note over User,Handler: Runtime
    User->>Gen: queries::config()
    Gen-->>User: Config
    User->>DB: HelixDB::new(path, config)
    DB->>Storage: HelixGraphStorage::new()
    Storage-->>DB: Arc<HelixGraphStorage>
    
    User->>DB: execute("GetUsers", params)
    DB->>DB: inventory::iter() collect handlers
    DB->>Handler: call handler(input)
    Handler->>Storage: query operations
    Storage-->>Handler: results
    Handler-->>DB: Response
    DB-->>User: Response
    User->>User: response.deserialize()
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Comments (4)

  1. helix-lib/Cargo.toml, line 4 (link)

    syntax: edition = "2024" is not a valid Rust edition. Valid editions are 2015, 2018, 2021.

  2. helix-lib/src/lib.rs, line 25-26 (link)

    logic: Type mismatch: queries::config() returns Option<Config> but this example treats it as Result. The generated function signature is pub fn config() -> Option<Config> (see build.rs:201), but documentation shows usage with ? operator which requires Result.

  3. helix-lib/README.md, line 71-72 (link)

    logic: Type mismatch: queries::config() returns Option<Config>, not Result, so the ? operator won't work here.

  4. helix-lib/src/lib.rs, line 123 (link)

    logic: This suggests using .unwrap_or_default() on Option<Config>, but Config doesn't implement Default. This will cause a compilation error. Use .expect() instead.

19 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@vrn21 vrn21 mentioned this pull request Dec 18, 2025
8 tasks
@vrn21
Copy link
Author

vrn21 commented Dec 18, 2025

Some more things to add:

  • Sadly I couldn't match the exact IO the queries were expecting: db.get_users() in [Feature]: Rust SDK bound directly with the db #104
  • Users would need to add a lot more than just helix-lib to their Cargo.toml atm (for compiling queries.rs)
  • There's a lot of json here and there; this much ser and deser would make it worser (slower) than a server-client setup with http; I'm not sure how we could make it as non json as possible though atm.
  • If this setup does look good, testing of hqls could be a lot easier??

@stayhydated
Copy link

Honestly, that's not really what i was expecting to address #104 . was thinking more into something like toasty or how spacetimedb declares it.
I was tinkering with #104 here (generated) without touching helixdb itself, since optionals and enums arent supported yet.

@el-yawd
Copy link
Contributor

el-yawd commented Dec 19, 2025

I might be being dumb here but, couldn't the embeddable API be just the storage API which HQL compile to?

@vrn21
Copy link
Author

vrn21 commented Dec 19, 2025

I might be being dumb here but, couldn't the embeddable API be just the storage API which HQL compile to?

I could say I've taken inspiration from the already existing sdk (https://github.com/HelixDB/helix-rs) and mostly have tried to mimic this usage, but doesn't using the actual storage api beat the entire need of hql? isn't hql supposed to be the actual high level interface to the db?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Rust SDK bound directly with the db

3 participants