-
Notifications
You must be signed in to change notification settings - Fork 673
spacetime dev client command #4068
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Add --client-command flag to specify client dev command - Add --server-only flag to skip client execution - Add spacetime.toml config file for project settings - Auto-detect client command from package.json/Cargo.toml/.csproj - Save detected command to spacetime.toml for future runs - Update spacetime init to set default client command - Add spacetime.toml to all templates with appropriate defaults - Update documentation
- Add --client-command flag to specify client dev command - Add --server-only flag to skip client execution - Add spacetime.toml config file for project settings - Auto-detect client command from package.json/Cargo.toml/.csproj - Save detected command to spacetime.toml for future runs - Update spacetime init to set default client command - Add spacetime.toml to all templates with appropriate defaults - Update documentation
….com/clockworklabs/SpacetimeDB into feature/spacetime-dev-client-command
- Client environment variables: The dev command now sets SPACETIMEDB_DB_NAME and SPACETIMEDB_HOST environment variables when spawning the client process. This fixes Rust and C# clients which read these env vars to determine which database to connect to. Previously, they would fall back to hardcoded defaults (e.g., quickstart-chat) and fail to connect. - C# module file watching: The file watcher now correctly handles C# modules which have source files directly in spacetimedb/ rather than in spacetimedb/src/. Previously, watching spacetimedb/src/ would fail with "Input watch path is neither a file nor a directory" for C# projects.
|
/update-llm-benchmark |
LLM Benchmark Results (ci-quickfix)
Compared against master branch baseline Generated at: 2026-01-21T14:28:05.429Z Failure Analysis (click to expand)Benchmark Failure AnalysisGenerated from: Summary
SpacetimeDB Benchmark Test Failures AnalysisRust / rustdoc_json FailuresGroup: Compile/Publish Errors (3 failures)Failure: t_002_scheduled_tableThe generated code: use spacetimedb::{table, reducer, ReducerContext, Table, ScheduleAt};
#[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))]
pub struct TickTimer {
#[primary_key]
#[auto_inc]
scheduled_id: u64,
scheduled_at: ScheduleAt,
}
#[reducer]
pub fn tick(_ctx: &ReducerContext, _timer: TickTimer) {
}
#[reducer(init)]
pub fn init(ctx: &ReducerContext) {
ctx.db
.tick_timer()
.insert(TickTimer {
scheduled_id: 0,
scheduled_at: ScheduleAt::EveryMicros(50_000),
});
}The golden example: use spacetimedb::{reducer, table, ReducerContext, ScheduleAt, Table};
use std::time::Duration;
#[table(name = tick_timer, scheduled(tick))]
pub struct TickTimer {
#[primary_key]
#[auto_inc]
pub scheduled_id: u64,
pub scheduled_at: ScheduleAt,
}
#[reducer]
pub fn tick(_ctx: &ReducerContext, _schedule: TickTimer) {
}
#[reducer(init)]
pub fn init(ctx: &ReducerContext) {
let every_50ms: ScheduleAt = Duration::from_millis(50).into();
ctx.db.tick_timer().insert(TickTimer {
scheduled_id: 0,
scheduled_at: every_50ms,
});
}The error: Explain the difference: The main issues in the generated code are:
Root cause: Documentation on how to properly specify scheduled attributes in structured tables might be unclear or lacking comprehensive examples. Recommendation: Update the documentation to clarify the use of scheduled columns and attributes, providing a clear example of how to set timed intervals properly. Failure: t_016_sum_type_columnsThe generated code: use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};
#[derive(SpacetimeType)]
pub struct Rect {
width: i32,
height: i32,
}
#[derive(SpacetimeType)]
pub enum Shape {
Circle(i32),
Rectangle(Rect),
}
#[table(name = drawing)]
pub struct Drawing {
#[primary_key]
id: i32,
a: Shape,
b: Shape,
}
#[reducer]
pub fn seed(ctx: &ReducerContext) {
let drawing = ctx.db.drawing();
for row in drawing.iter() {
drawing.delete(&row);
}
drawing.insert(Drawing {
id: 1,
a: Shape::Circle(10),
b: Shape::Rectangle(Rect { width: 4, height: 6 }),
});
}The golden example: use spacetimedb::{reducer, table, ReducerContext, SpacetimeType, Table};
#[derive(SpacetimeType, Clone, Debug)]
pub struct Rect {
pub width: i32,
pub height: i32,
}
#[derive(SpacetimeType, Clone, Debug)]
pub enum Shape {
Circle(i32),
Rectangle(Rect),
}
#[table(name = drawing)]
pub struct Drawing {
#[primary_key]
pub id: i32,
pub a: Shape,
pub b: Shape,
}
#[reducer]
pub fn seed(ctx: &ReducerContext) {
ctx.db.drawing().insert(Drawing {
id: 1,
a: Shape::Circle(10),
b: Shape::Rectangle(Rect { width: 4, height: 6 }),
});
}The error: Explain the difference: The generated code lacked public visibility on struct fields necessary for serialization and actual utilization within the SpacetimeDB context. Root cause: Insufficient documentation on the visibility requirements for SpacetimeType structures may lead to confusion regarding struct accessibility. Recommendation: Emphasize the necessity of public fields with detailed examples for types and their usage in the documentation. Group: Other Failures (6 failures)Failure: t_003_struct_in_tableThe generated code: use spacetimedb::{table, reducer, ReducerContext, SpacetimeType};
#[derive(SpacetimeType)]
pub struct Position {
x: i32,
y: i32,
}
#[table(name = entity)]
pub struct Entity {
#[primary_key]
id: i32,
pos: Position,
}
#[reducer(init)]
pub fn init(_ctx: &ReducerContext) {}The golden example: use spacetimedb::{table, SpacetimeType};
#[derive(SpacetimeType, Clone, Debug)]
pub struct Position {
pub x: i32,
pub y: i32,
}
#[table(name = entity)]
pub struct Entity {
#[primary_key]
pub id: i32,
pub pos: Position,
}The error: Explain the difference: While the generated code correctly defines a table and a reducer, the lack of public access for fields in the Root cause: The documentation may not sufficiently stress the importance of field visibility for user-defined types in SpacetimeDB. Recommendation: Include explicit instructions or examples that reinforce the need for Failure: t_012_spacetime_product_typeThe generated code: use spacetimedb::{table, reducer, ReducerContext, Table, SpacetimeType};
#[derive(SpacetimeType)]
struct Score {
left: i32,
right: i32,
}
#[table(name = result)]
struct ResultRow {
#[primary_key]
id: i32,
value: Score,
}
#[reducer]
fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {
ctx.db.result().insert(ResultRow { id, value: Score { left, right } });
}The golden example: use spacetimedb::{reducer, table, ReducerContext, SpacetimeType, Table};
#[derive(SpacetimeType, Clone, Debug)]
pub struct Score {
pub left: i32,
pub right: i32,
}
#[table(name = result)]
pub struct ResultRow {
#[primary_key]
pub id: i32,
pub value: Score,
}
#[reducer]
pub fn set_score(ctx: &ReducerContext, id: i32, left: i32, right: i32) {
ctx.db.result().insert(ResultRow { id, value: Score { left, right } });
}The error: Explain the difference: The missing public access on the Root cause: Again, the documentation lacks sufficient emphasis on public attributes for user-defined types in the context of SpacetimeDB. Recommendation: Add a guide on the visibility and accessibility requirements for structs that are intended to be used as database records. C# / docs Failures (5 total)Group: Other Failures (4 failures)Failure: t_014_elementary_columnsThe generated code: using SpacetimeDB;
public static partial class Module
{
[SpacetimeDB.Table(Name = "Primitive", Public = true)]
public partial struct Primitive
{
[SpacetimeDB.PrimaryKey]
public int Id;
public int Count;
public long Total;
public float Price;
public double Ratio;
public bool Active;
public string Name;
}
[SpacetimeDB.Reducer]
public static void Seed(ReducerContext ctx)
{
ctx.Db.Primitive.Insert(new Primitive
{
Id = 1,
Count = 2,
Total = 3000000000L,
Price = 1.5f,
Ratio = 2.25,
Active = true,
Name = "Alice"
});
}
}The golden example: using SpacetimeDB;
public static partial class Module
{
[Table(Name = "Primitive")]
public partial struct Primitive
{
[PrimaryKey]
public int Id;
public int Count;
public long Total;
public float Price;
public double Ratio;
public bool Active;
public string Name;
}
[Reducer]
public static void Seed(ReducerContext ctx)
{
ctx.Db.Primitive.Insert(new Primitive
{
Id = 1,
Count = 2,
Total = 3000000000L,
Price = 1.5f,
Ratio = 2.25,
Active = true,
Name = "Alice"
});
}
}The error: Explain the difference: The generated code incorrectly added the Root cause: There may be unclear directives about accessibility requirements for struct definitions within the documentation. Recommendation: Clarify in the documentation when to use accessibility modifiers and provide straightforward examples of valid struct declarations. This analysis summarizes actionable insights for documentation enhancements based on SpacetimeDB benchmark failures. By updating documentation to address the common pitfalls outlined above, it can greatly reduce frustration and improve the developer experience. |
Description of Changes
Adds integrated client development server support to
spacetime dev, allowing it to automatically start and manage the client application alongside the SpacetimeDB module.Key features:
spacetime devnow automatically starts the client dev server (e.g.,npm run dev,pnpm dev,cargo run) after publishing the modulespacetime.jsonproject config file with arunfield to specify the client commandpackage.json(with dev script),Cargo.toml, or.csprojfilesSPACETIMEDB_DB_NAMEandSPACETIMEDB_HOSTenvironment variables for the client processsh -con Unix,cmd /Con Windows) for proper argument handlingNew CLI options:
--client-command <COMMAND>- Override the client command from config/auto-detect--server-only- Only run the server module without starting the clientNew
spacetime.jsonformat:{ "run": "pnpm dev" }Config resolution order:
--client-commandCLI flag (highest priority)spacetime.jsonconfig filespacetime.jsonfor future runs)This is the first step toward a richer project config that will eventually include
generateandpublishoptions.Note: The PR for "Implement spacetime.json project config file" may override this PR's
spacetime_config.rsand setup code with a more comprehensive implementation.API and ABI breaking changes
None - this is additive functionality.
Expected complexity level and risk
2 - The changes are well-contained within the CLI crate (
spacetime_config.rs,dev.rs,init.rs). The client process management uses standard tokio process spawning withkill_on_dropfor cleanup.Testing
Recording.2026-01-20.140159.mp4
spacetime init --template quickstart-chat-typescriptcreatesspacetime.jsonwith correctruncommandspacetime devstarts both the module watcher and client dev serverspacetime dev --server-onlyonly starts the module watcherspacetime dev --client-command "npm start"overrides the configspacetime.jsonautomatically)spacetime devis stopped (Ctrl+C)SPACETIMEDB_DB_NAME,SPACETIMEDB_HOST) are available to the client--client-command "nonexistent-cmd") shows clear error message