feat: expand plugin surface to mirror buckaroo server (load_expr, diagnostics, backend)#3
Open
paddymul wants to merge 2 commits into
Open
feat: expand plugin surface to mirror buckaroo server (load_expr, diagnostics, backend)#3paddymul wants to merge 2 commits into
paddymul wants to merge 2 commits into
Conversation
…gnostics, backend)
Brings the buckaroo-tauri plugin closer to parity with `buckaroo.server`'s
HTTP surface. Adds the two endpoint passthroughs that were missing
(`load_expr`, `diagnostics`) and threads two new optional fields
(`mode`, `backend`) through the existing `buckaroo_load_path` so hosts
can route a parquet via the xorq push-down backend without separately
extracting a build_dir.
## Rust (crates/buckaroo-tauri/src)
- `LoadPathArgs` gains `mode: Option<String>` and `backend: Option<String>`.
Forwarded into the POST body verbatim when present; otherwise the
Layer-3 contract (server defaults) holds. Pre-existing callers that
pass only `path` (+ optional `session`) are unaffected.
- New `LoadExprArgs` + `buckaroo_load_expr` command. POSTs `/load_expr`
with `{build_dir, session?, project_root?, prompt?, component_config?}`
and opens the internal WS to the returned session — same shape as
`buckaroo_load_path` but for the xorq-build-dir-driven path.
- New `buckaroo_diagnostics` command. Thin GET passthrough for the
server's `/diagnostics` endpoint; returns the JSON blob verbatim so
host UIs can surface server version, uptime, installed extras, etc.
- Both new commands registered in `init()`.
## JS adapter (packages/buckaroo-tauri-adapter)
- `loadPath` gains an `opts?: { mode?, backend?, session? }` argument
that's forwarded to the Rust command. Existing single-arg callers
(`loadPath(path)`) keep working.
- New `loadExpr(build_dir, opts?)` helper paired with `buckaroo_load_expr`.
- Both exported from `index.ts`.
## Why
`buckaroo.server` already supports a richer surface than the plugin
exposes:
| Endpoint | Plugin command before | Plugin command after |
|--------------|------------------------------|-----------------------|
| `/health` | `buckaroo_health` (WS state) | unchanged |
| `/diagnostics` | — | `buckaroo_diagnostics`|
| `/load` | `buckaroo_load_path` | + `mode` + `backend` |
| `/load_expr` | — | `buckaroo_load_expr` |
`mode` / `backend` forwarding on `/load` pairs with the
[`feat(server): /load gains backend=xorq` change in buckaroo](buckaroo-data/buckaroo#840):
hosts that already materialised a parquet on disk can opt into
XorqInfiniteBuckaroo's push-down query execution by passing
`{ mode: "buckaroo", backend: "xorq" }`, avoiding the eager-pandas
load that was the only path before.
## Test plan
- [x] `cargo build` clean on the Rust crate.
- [x] Manual: existing single-arg `loadPath(path)` still works.
- [ ] Manual: `loadPath(path, { mode: "buckaroo", backend: "xorq" })`
against a sidecar that has the matching server change produces a
XorqInfiniteBuckaroo session (verified end-to-end via the
xorq-desktop integration that motivated this PR).
- [ ] Playwright tests on the example app still pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
… race
Adds `listenForInitialState()` — a variant of `waitForInitialState()`
that awaits the underlying `listen()` subscription before returning, so
the caller can fire a load call immediately afterwards without losing
the resulting `initial_state` push to a registration race.
Pattern:
const received = await listenForInitialState();
await loadPath(path, { mode: "buckaroo", backend: "xorq" });
const initial = await received;
`waitForInitialState()` is left in place for hosts that pre-attach the
listener and only call `loadPath` later (the race doesn't bite there).
A docstring warning calls out the failure mode so new callers know
to reach for the race-safe variant when the two operations are
back-to-back.
## Background
`waitForInitialState()` returns a Promise immediately but the
`listen("buckaroo:msg", ...)` call inside is async — Tauri's event
channel needs an IPC round-trip to register the subscription. If the
caller fires `loadPath` next, the load_path IPC and the listen IPC
race; if load_path wins, the server's initial_state push arrives
before the listener attaches and Tauri drops it (no pre-subscription
buffering). The Promise then hangs forever waiting for a message
that already fled.
Confirmed in xorq-desktop integration: clicking a fast-path entry
like `batting` (parquet path returned in ~1 ms) reliably stalled on
"loading into sidecar + awaiting initial_state…" until the inline
fix landed. With `listenForInitialState()` the same flow lands the
view in milliseconds.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the gap between the plugin's IPC surface and the buckaroo server's HTTP surface. Two new commands, two new optional fields on the existing load command, matching JS adapter helpers.
buckaroo_load_pathgainsmodeandbackendoptional args, forwarded into the POST body. Pre-existing single-arg callers unaffected.buckaroo_load_exprcommand — POSTs/load_exprwith{build_dir, session?, project_root?, prompt?, component_config?}and opens the internal WS. Counterpart tobuckaroo_load_pathfor the xorq-build-dir-driven path.buckaroo_diagnosticscommand — thin GET passthrough for/diagnostics.loadPath(path, opts?)—opts: { mode?, backend?, session? }.loadExpr(build_dir, opts?)— new helper paired withbuckaroo_load_expr.Why
buckaroo.serveralready supports a richer surface than the plugin exposes:/healthbuckaroo_health(WS state)/diagnosticsbuckaroo_diagnostics/loadbuckaroo_load_pathmode+backend/load_exprbuckaroo_load_exprmode/backendforwarding pairs with the matchingfeat(server): /load gains backend=xorqbuckaroo PR: hosts that already materialised a parquet on disk can opt into XorqInfiniteBuckaroo's push-down query execution by passing{ mode: "buckaroo", backend: "xorq" }instead of eager-pandas-loading the file.Test plan
cargo buildclean.loadPath(path)single-arg callers still work.loadPath(path, { mode: "buckaroo", backend: "xorq" })against a sidecar with the matching server change produces a XorqInfiniteBuckaroo session./loaddefaults — extending coverage is a follow-up).Compatibility
LoadPathArgsareOption<String>with#[serde(default)]— old JSON payloads deserialize unchanged.loadPath's second arg is optional — old single-arg call sites compile and run identically.🤖 Generated with Claude Code