3334 Commits

Author SHA1 Message Date
bradleyshep cea601ffa4 Fix various TS templates (#4360)
# Description of Changes

Fix `withModuleName` -> `withDatabaseName` in server-side code across
multiple TypeScript templates. The 2.0 SDK renamed this method, but
several templates still used the old 1.x API name, causing a runtime
error (`DbConnection.builder(...).withUri(...).withModuleName is not a
function`).

**Files changed:**
- `templates/nuxt-ts/server/api/people.get.ts`
- `templates/remix-ts/app/lib/spacetimedb.server.ts`
- `templates/nextjs-ts/lib/spacetimedb-server.ts`
- `templates/nodejs-ts/src/main.ts`
- `templates/deno-ts/src/main.ts`
- `templates/keynote-2/src/connectors/spacetimedb.ts`

# API and ABI breaking changes

None. This aligns templates with the existing 2.0 SDK API.

# Expected complexity level and risk

1 — Trivial string replacement across template files. No logic changes.

# Testing

- [ ] Run `spacetime dev --template nuxt-ts` and verify the Nuxt SSR
server API (`/api/people`) connects without `withModuleName is not a
function` error
- [ ] Run `spacetime dev --template nextjs-ts` and verify the
server-side SpacetimeDB connection works
- [ ] Run `spacetime dev --template remix-ts` and verify the server-side
SpacetimeDB connection works
2026-02-20 15:05:45 +00:00
Shubham Mishra e2f8a60759 Case conversion (#4263)
# Description of Changes

Update the Default casing policy to `snake_case` for `RawModuleDefV10`.

Messy PR contains changes at different places, so that CI can pass:

Here are the main changes as follows:
- `bindings-macro` & `bindings` crate: `name` macro in Indexes for
canonical name and supply it to `RawModuleDefV10` via `ExplicitNames`.
- `bindings-typescript`: 
- Changes has been reviewed through this PR -
https://github.com/clockworklabs/SpacetimeDB/pull/4308.
   
- `binding-csharp`: a single line change to pass `sourceName` of index
instead of null.
- `codegen`:
  
- Changes has been merged from branch -
https://github.com/clockworklabs/SpacetimeDB/pull/4337.
  
- Except a fix in rust codegen to use canonical name in Query buillder
instead of accessor.
  
- `lib/db/raw_def`: Extends `RawDefModuleV10` structure to support case
conversion.
  
- `schema` crate:
- `validate/v9` - Nothing itself should change or changes in v9
validation logic but the file contains a `CoreValidator` which is shared
with `validate/v10`. No test have t be updated to `validate/v9` which
ensures we aren't regressing it.
- `validate/v10`: This is the main meat, look at the new tests added in
bottom to understand what it does.
     
   -  Rest of the files are either test updates or module bindings. 
     
    ## Testing:
1. Extensive unit tests have been added to verify generated `ModuleDef`
is correct.
2. I have done some e2e testing to verify rust codegen with rust and
typescript modules.
3. I would have like to do more testing for other codegens , I am
continue doing .

I have removed `sql.py` smoketest, as that seems to be already migated
in new framework and was headache to update.

## Expected complexity level and risk
4, It could have side-effect which aren't easily visible.


 
 
 
 
 
 -  -  -

---------

Signed-off-by: Shubham Mishra <shivam828787@gmail.com>
Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
Co-authored-by: Noa <coolreader18@gmail.com>
Co-authored-by: = <cloutiertyler@gmail.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@clockworklabs.io>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io>
2026-02-20 10:44:29 +00:00
Ryan d965569397 [C#] Cononical Names and Casing Settings in ModuleDef (#4368)
This is the implementation of the "Nice to Have in 2.0" items from #4295

# Description of Changes
* Propagate the module’s case-conversion policy and each explicit
canonical name (tables, reducers, procedures, views, indexes) into
`RawModuleDefV10`, so runtime consumers receive the same metadata
emitted by the Rust toolchain.
* Implement support for `[SpacetimeDB.Settings]` + explicit `Name = ...`
attribute overrides in the C# module bindings generator.
* Adds an `explicitnames` fixture to the Codegen Test suite to cover the
generated registration calls, ensuring accessor vs. canonical names stay
in sync.
# API and ABI breaking changes
None. Generator + runtime internals only; no public surface changes.

# Expected complexity level and risk
2 – localized to the C# codegen/runtime plumbing, validated by focused
tests.

# Testing
- [X] Compiled CLI changes locally and ran C# regression tests.
- [X] Ran `dotnet test
crates/bindings-csharp/Codegen.Tests/Codegen.Tests.csproj -c Release` to
verify code tests pass
2026-02-20 06:31:07 +00:00
Zeke Foppa e9977ffa81 gitignore AI agent config dirs (#4365)
# Description of Changes

Just adding gitignore lines for AI agent stuff so I don't commit my
configs.

# API and ABI breaking changes

gitignore only

# Expected complexity level and risk

1

# Testing

- [x] My files are no longer showing up in git 🤷

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-20 02:54:04 +00:00
Jeffrey Dallatezza 9cf4af4ff2 Add more debug logging to the typescript client (#4356)
# Description of Changes

This adds some logging utilities, that will probably be helpful for
debugging issues. `stdbLogger` can now accept lazy messages. If you call
`setGlobalLogLevel`, that will set a log level globally. It is set to
`info` by default, but when troubleshooting, we can ask people to run
`setGlobalLogLevel('trace')` and share more detailed logs.

In this PR, it adds a new new logs at the `trace` level:
 - All outgoing messages to the server
 - All incoming messages from the server
- After handling a server message, we log the number of triggered row
callbacks

There are also some formatting niceties to truncate large arrays and
redact fields that look like credentials.

We are also using `safe-stable-stringify` to handle some cases that
would be errors in `JSON.stringify`.

# API and ABI breaking changes

This adds the `setGlobalLogLevel` function, which is useful for
debugging.

# Expected complexity level and risk

1.5 - the only real risk here is that 

# Testing

This has some tests of formatting in `logger.test.ts`.
2026-02-20 00:36:18 +00:00
Zeke Foppa dd3f7666bc Fix template global.json under Windows (#4357)
# Description of Changes

Make the `global.json` files under `templates` into literal copies of
the root one, instead of symlinks. The symlinks were causing template
breakage when the CLI was built under windows.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] Changing a template's global.json causes `cargo ci
global-json-policy` to fail
- [x] Making a template's global.json into a symlink also causes `cargo
ci global-json-policy` to fail

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-19 23:33:51 +00:00
Phoebe Goldman 2c8f62e019 Make Rust test clients listen for reducer errors (#4359)
# Description of Changes

Prior to this commit, if a reducer call failed during a test in the Rust
SDK test suite, the client would hang, as it generally didn't register
callbacks when invoking reducers. This could mask some bugs, causing the
tests to fail with TIMEOUT rather than a useful message. For example, we
relied on consistency between all of the test modules, which was broken
by our not having updated the C++ bindings library to use the new
case-conversion scheme. This meant that the client was sending reducer
calls with incorrect reducer names to at least one database per test
run, which would result in a `Panic` status or an `Err(Err(_))` outcome.

With this commit, the SDK test clients are updated to inspect the exit
status of reducers they invoke, and (except for intentional reducer
failures) to panic the test client when encountering a reducer error or
panic.

# API and ABI breaking changes

N/a

# Expected complexity level and risk

1

# Testing

- [x] Automated tests passed locally.
- [x] Intentionally broke reducer calls via the 2.0 WS API, causing them
to skip the call and unconditionally respond with `Status::Panic`.
Observed "loud" failures in the test suite with non-`TIMEOUT` output
that looked more debuggable to me.
2026-02-19 23:28:37 +00:00
Tyler Cloutier b2bb2180c5 Fix spacetime dev watch filtering and improve quickstart copy-paste experience (#4317)
## Summary
- Fix `spacetime dev` failing on C# projects by watching the module
directory itself instead of hardcoded `spacetimedb_dir/src/` (which
doesn't exist for C# templates)
- Add layered file-watch filtering to avoid triggering rebuilds on build
artifacts:
1. Always-ignore dirs (`target/`, `bin/`, `obj/`, `node_modules/`, etc.)
  2. Always-watch exceptions (`.env.local`, `spacetime.*.local.json`)
  3. `.gitignore` rules from global, project, and module levels
- Suppress init's generic "Next steps" message when called from
`spacetime dev`, print a dev-appropriate `cd` hint instead when a new
project is created in a subdirectory
- Update 12 quickstart docs to tell users to open a new terminal and `cd
my-spacetime-app` before running CLI commands

## Test plan
- [x] `cargo build -p spacetimedb-cli` compiles successfully
- [ ] `spacetime dev --template basic-cs` no longer errors with "Input
watch path is neither a file nor a directory"
- [ ] Modifying a `.cs` file in `spacetimedb/` triggers a rebuild
- [ ] Build artifacts in `obj/`/`bin/` do not trigger rebuilds
- [ ] Rust projects (`spacetimedb/src/` exists) continue to work as
before
- [ ] `spacetime dev --template basic-cs` from a non-project directory
prints the "Tip: cd" hint, not the generic "Next steps"
- [ ] `spacetime init` standalone still prints "Next steps" as before

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-19 23:12:34 +00:00
Noa f2ab8be1d1 [TS] Improve how exceptions get rendered in messages (#4347)
# Description of Changes

This changes all types of functions to catch and process `SenderError`,
which seems like something we want to do anyway, since we have examples
of throwing `SenderError` in procedures. For that case, before:

```
The module instance encountered a fatal error: js error Uncaught API returned status 401
	at <anonymous> (src/index.ts:36:13)


```

after:
```
The module instance encountered a fatal error: API returned status 401
```
(it doesn't have the stack trace because a `SenderError` is more akin to
an error return than an exception).

Exception from procedure before:
```
The module instance encountered a fatal error: js error Uncaught TypeError: Cannot read properties of undefined (reading 'abcdef')
	at <anonymous> (src/index.ts:35:7)


```

After:
```
The module instance encountered a fatal error: Uncaught TypeError: Cannot read properties of undefined (reading 'abcdef')
	at <anonymous> (src/index.ts:35:7)
```

# Expected complexity level and risk

2

# Testing

- [x] Verified that exceptions thrown
2026-02-19 23:06:14 +00:00
Piotr Sarnacki 1a0e36e3a9 Warn about publishing DBs from non-local/non-dev spacetime.json in dev (#4350)
# Description of Changes

At the moment, we warn about using a database with a name from
`spacetime.json` in `dev`, but it only checks the root database. This PR
adds support for children, too.

# Expected complexity level and risk

2

# Testing

- [x] Added automated tests
- [x] Tested locally

With the following configs:

```json
# spacetime.json
{
  "server": "maincloud",
  "module-path": "./spacetimedb",
  "database": "main",
  "children": [{
    "database": "foo",
    "module-path": "foo"
  }, {
    "database": "bar",
    "module-path": "bar"
  }]
}
```

```json
# spacetime.local.json
{
  "children": [
    {
      "database": "foo-local"
    }
  ],
  "database": "main"
}
```

This is the output of `spacetime dev`:

```
✓ Using configuration from ./spacetime.json, ./spacetime.local.json

Starting development mode...
Databases: main, foo-local, bar
Watching for changes in 3 directories:
  - /Users/drogus/code/clockwork/spacetime-config-test/my-spacetime-app/spacetimedb
  - /Users/drogus/code/clockwork/spacetime-config-test/my-spacetime-app/foo
  - /Users/drogus/code/clockwork/spacetime-config-test/my-spacetime-app/bar
Warning: You are trying to publish databases in dev mode that were defined in the main spacetime.json file: bar
Do you want to proceed? [Y/n]
```

---------

Signed-off-by: Piotr Sarnacki <drogus@gmail.com>
Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
2026-02-19 22:34:36 +00:00
John Detter 0b2462046a Update benchmark docs (#4345)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

This updates the PhoenixNap config that we used for running the
benchmarks

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

None this is docs

# Expected complexity level and risk

None this is docs

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] The docs are correct

---------

Signed-off-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-02-19 22:30:33 +00:00
Noa 178a7f0e60 Fix warnings in regen-cpp-moduledef (#4355)
# Description of Changes

This has been annoying me for a bit. We don't care if we use println in
a dev tool.

# Expected complexity level and risk

1

# Testing

- [x] The warnings are gone.
2026-02-19 21:34:27 +00:00
John Detter 27bb9f8edf Remove database names in quickstarts (#4354)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

- For the quickstarts we don't want to pass a database name during
`spacetime dev --template ...`

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

None - this is just docs

# Expected complexity level and risk

None - this is just docs

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] All quickstarts no longer pass a database name during `spacetime
dev --template ...`
2026-02-19 21:18:29 +00:00
Piotr Sarnacki d9a1ce8153 Fix publishing and generating from subdirs if config is present (#4351)
# Description of Changes

When config is present and no explicit `module-path` has been passed, we
should be resolving paths from the config and defaults relative to the
config file

# Expected complexity level and risk

2

# Testing

- [x] Tested locally
2026-02-19 19:37:20 +00:00
Ryan 1d48c08f46 Update to generated C# template package version (#4349)
# Description of Issue

When you run `spacetime dev --template basic-cs` and give it the default
inputs, the `.csproj` files it generates use the package versions of
`1.*` rather than `2.*`.
The relative path locations are:
* `.\my-spacetime-app\client.csproj`
* `.\my-spacetime-app\spacetimedb\StdbModule.csproj`
This is deceptive because in `.\SpacetimeDB\templates\basic-cs`, each
file has a `2.0.*` for the package versions.

This issue results in an error when trying to use a C# template, as
specific 2.0 features are not properly detected.

This happens because:
1. When you run `spacetime dev` outside an existing project, the dev
subcommand notices the missing spacetimedb/ directory and internally
calls `init::exec_with_options` with your requested template
(`basic-cs`) to scaffold a project first. That logic lives in
`crates/cli/src/subcommands/dev.rs` and triggers whenever `dev` is asked
to initialize a template before continuing.
2. The template assets under `templates/basic-cs` indeed still contain
`2.0.*` package references, but after the embedded files are copied, the
initializer runs `update_csproj_client_to_nuget` and
`update_csproj_server_to_nuget`. These functions rewrite the first
`.csproj` they find in the client/server directories to depend on NuGet
packages rather than local project references.
3. Both helpers call `get_spacetimedb_csharp_runtime_version()` /
`get_spacetimedb_csharp_clientsdk_version()`, and those helpers
currently hard-code `"1.*"` as the version string.

That’s why your freshly generated `client.csproj` and
`spacetimedb/StdbModule.csproj` end up with `1.*` package versions even
though the template files started at `2.0.*`

# Description of Changes

Updates the `get_spacetimedb_csharp_runtime_version()` and
`get_spacetimedb_csharp_clientsdk_version()` functions to return `2.*`

# API and ABI breaking changes

No API/ABI changes

# Expected complexity level and risk

1 - Low

# Testing

- [X] Ran `spacetime dev --template basic-cs` locally and confirmed
`.csproj` files generate with `2.*` package versions.
2026-02-19 18:21:57 +00:00
doug ae8c9159b3 Add ConnectionManager for robust React lifecycle handling (#4028)
## Summary
- Add `ConnectionManager` singleton that uses reference counting and
deferred cleanup to handle React StrictMode's double-mount behavior
- Implement TanStack Query-style pattern: `retain()` / `release()`
instead of direct connect/disconnect
- Use `useSyncExternalStore` for tear-free state reads in React

## Changes
- **New:** `src/sdk/connection_manager.ts` - Core ConnectionManager
implementation
- **Modified:** `src/react/SpacetimeDBProvider.ts` - Now uses
ConnectionManager
- **Modified:** `src/react/connection_state.ts` - Simplified type,
imports from ConnectionManager
- **Modified:** `src/sdk/db_connection_builder.ts` - Added `getUri()`
and `getModuleName()` methods
- **Modified:** `src/sdk/db_connection_impl.ts` - Minor type updates for
ConnectionManager integration
- **New:** `tests/connection_manager.test.ts` - 33 unit tests
- **Docs:** Added React Integration section to TypeScript reference
- **Docs:** Added StrictMode compatibility note to README

## Test plan
- [x] `pnpm test` passes (104 tests)
- [x] `pnpm build` passes
- [x] Manual browser test with React StrictMode - single WebSocket
connection

---

## Motivation

### The Problem

React StrictMode double-mounts components in development to help catch
bugs:

1. Mount → creates WebSocket connection
2. Unmount → destroys WebSocket connection
3. Remount → creates **another** WebSocket connection

Without ConnectionManager, you get either:
- **Two connections** (if you don't clean up on unmount)
- **Broken connection** (if you clean up on unmount, the remount races
with cleanup)

### Why ConnectionManager? (vs alternatives)

| Alternative | Problem |
|-------------|---------|
| Don't clean up on unmount | Leaks connections, memory leaks, stale
subscriptions |
| Disable StrictMode | Hides real bugs, production still has edge cases
|
| Connection in module scope | React can't react to state changes, no
`useSyncExternalStore` |

**ConnectionManager approach** (TanStack Query pattern):
- Reference counting: multiple components share one connection
- Deferred cleanup: `setTimeout(0)` lets StrictMode remount cancel
cleanup
- External store: connection state lives outside React but syncs
properly

---

## Why Two `useSyncExternalStore` Usages?

The SDK now has two places using `useSyncExternalStore`. They solve
different problems:

| | `useTable` | `ConnectionManager` |
|---|---|---|
| **Subscribes to** | Table row changes | Connection state changes |
| **External store** | `DbConnection.db.tableName` callbacks |
`ConnectionManager` singleton |
| **Re-renders when** | Row inserted/deleted/updated | `isActive`,
`identity`, `error` change |
| **Manages lifecycle?** |  No - assumes connection exists |  Yes -
owns connect/disconnect |

### `useTable` assumes a connection exists

```tsx
// useTable.ts - subscribes to TABLE DATA
useEffect(() => {
  const connection = connectionState.getConnection()!;  // assumes this exists
  if (connectionState.isActive && connection) {
    const cancel = connection.subscriptionBuilder().subscribe(query);
    return () => cancel.unsubscribe();
  }
}, [...]);
```

### `ConnectionManager` manages WHEN the connection exists

```tsx
// OLD SpacetimeDBProvider - broken with StrictMode
useEffect(() => {
  const conn = builder.build();    // Creates WebSocket
  return () => conn.disconnect();  // Destroys WebSocket
}, [builder]);
// StrictMode: build → disconnect → build = TWO CONNECTIONS RACING

// NEW SpacetimeDBProvider - works with StrictMode  
useEffect(() => {
  ConnectionManager.retain(key, builder);   // refCount++, maybe create
  return () => ConnectionManager.release(key); // refCount--, deferred cleanup
}, [key, builder]);
// StrictMode: retain(1) → release(0, schedule) → retain(1, cancel) = ONE CONNECTION
```

### The Layered Architecture

```
ConnectionManager (lifecycle: retain/release, deferred cleanup)
    ↓
SpacetimeDBProvider (React context + useSyncExternalStore for connection state)
    ↓
useTable (useSyncExternalStore for table data)
```

- `useTable` syncs **data** from an existing connection
- `ConnectionManager` syncs **connection state** AND manages **when the
connection exists**

---------

Co-authored-by: Jeffrey Dallatezza <jeffreydallatezza@gmail.com>
2026-02-19 16:21:19 +00:00
Noa 098afaf1a5 [TS] Improve autogen autocompletion and typing (#4309)
# Description of Changes

All types are now defined and exported in `module_bindings/types.ts`,
meanings there's only one module you need to import from to access
types.

# Expected complexity level and risk

2

# Testing

n/a, no change in behavior.
2026-02-19 06:17:02 +00:00
joshua-spacetime 41cfbbc7e0 Update subscription and query builder docs (#4329)
# Description of Changes

This patch does the following:

- Adds api reference docs for the module-side query builder in the view
docs
- Merges the client sdk and subscription docs pages
- Keeps subscription and client overview docs high-level (moved all api
docs to the language reference docs)
- Replaces SQL examples in the docs with the query builder
- Replaces SQL subscriptions in the templates with the query builder

Note, the last commit in this patch set transitions the templates over
to use the query builder instead of SQL subscriptions. This will break
them temporarily until #4000 merges.

Also note, a lot of this was AI assisted. It can still be improved upon,
but it's in a better state than it was.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

N/A

---------

Signed-off-by: joshua-spacetime <josh@clockworklabs.io>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
2026-02-19 03:59:33 +00:00
Jeffrey Dallatezza 45bc0451ac Add more tests for typescript client and fix some bugs (#4307)
# Description of Changes

This fixes a couple issues:
 - We are now using the `SendDroppedRows` flag for unsubscribe messages.
 - We parse reducer errors as strings now when throwing errors.
- `useTable` was not doing client-side filtering correctly for object
types (Timestamp, ConnectionId, Identity)
- `useTable` was not always recomputing snapshots when it needed to,
because it couldn't distinguish between two events if they were caused
by reducers called by other connections (or two subscription applied
events). All events how have a client-generated id attached, so we can
tell if there was actually a new event processed.

Once we have per-query storage, we can purge the client-side filtering
code.

This also adds some tests to cover these cases, and includes a bit of
refactoring.

Another change added here is to use `SenderError` in the typescript SDK
for errors that were returned by reducers (which throw `SenderError` in
typescript modules).


# Expected complexity level and risk

1

# Testing

This has some new tests added.

Much of the `useTable` logic was tested manually.
2026-02-19 03:00:16 +00:00
Piotr Sarnacki c0442ea146 Add smoketests for template generation (#4000)
# Description of Changes

Basic tests for templates, the test tries to generate each of the
template, build and publish the SpacetimeDB part, and build or type
check the client side.

This PR also includes bindings for all of the clients as it's needed for
the tests to work and given the choices to either generate during the
test run or include the bindings in git we chose the latter. This makes
it consistent across the templates as some of them already included
bindings.

# Expected complexity level and risk

1

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io>
2026-02-19 02:51:05 +00:00
Jason Larabie 34aa9654fd Docs - add shared C++ version notice inside first C++ tab across docs (#4348)
# Description of Changes
- Added a shared component with a message for C++ on the version pinning
- Updated every doc that has a C++ tab to include the new message

# API and ABI breaking changes

N/A

# Expected complexity level and risk

2 - Small document change but used a shared component

# Testing
- [x] Tested locally with pnpm dev
- [x] Hosted on my personal site to double check the shared component
2026-02-19 00:20:47 +00:00
Noa ea0e01edb7 Fixes for procedure example in docs (#4346)
# Description of Changes

The maximum http timeout (500ms) was too low for the OpenAI API to have
time to respond, so I raised it, and verified that the rust and
typescript examples work. Csharp wasn't building at all for some reason
(`Workload installation failed: Unable to load the service index for
source https://api.nuget.org/v3/index.json.`?)

# Expected complexity level and risk

1

# Testing

- [x] Manually tested these changes
2026-02-18 23:21:23 +00:00
Ryan ba20c552f5 [C#] Spacetime 2.0 Query Builder behavior validation (#4333)
# Description of Changes

* Extend the C# regression client to cover compound Query Builder
predicates (range filters + boolean combinators) so we ensure the
generated SQL matches the documentation promises. See: `Program.cs`
* Updated the C# documentation snippets to use `.AddQuery(...)` over raw
SQL. See: `00400-subscriptions.md` and `00400-sdk-api.md`

# API and ABI breaking changes

No changes to API or ABI

# Expected complexity level and risk

1

# Testing

- [X] Ran regression tests locally
2026-02-18 23:10:03 +00:00
Noa 354f20ff34 Return ModuleInfo from check_module_validity (#4339)
# Description of Changes

Was changed in #4312.

# Expected complexity level and risk

1
2026-02-18 23:07:09 +00:00
Jason Larabie 0590ab00f8 Rust docs updated for name to accessor (#4344)
# Description of Changes

- Updated all markdown files that call out `#[spacetimedb::table(name`
to `#[spacetimedb::table(accessor`
- Updated the LLM details on the same change

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1 - Small rework in documentation to use the new 

# Testing

- [x] Did a small double check on name vs accessor locally
- [x] Codex tested all the LLM answers
2026-02-18 23:06:09 +00:00
Piotr Sarnacki 39bf47e025 spacetime.json related fixes and improvements (#4332)
# Description of Changes

This PR fixes a bunch of issues and brings some improvements related to
`spacetime.json` config file

# API and ABI breaking changes

-

# Expected complexity level and risk

3

This PR is changing several places that are called during many of the
CLI commands.

# Testing

- [x] Added some automated tests
- [ ] Tested locally
2026-02-18 22:54:56 +00:00
Noa d0b9254ba7 Fix CI error stemming from cargo update (#4341)
# Description of Changes

Now we only `cargo update` the dependencies of the module, not of
`spacetimedb-cli`.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-02-18 20:47:13 +00:00
joshua-spacetime 8287408ca2 Fix query optimization for semijoins (#4287)
# Description of Changes

Fixes a planner bug where certain join queries could fail with:
```
Could not compute positional arguments during query planning
```

The reason was that in the process of rewriting the query with
semijoins, the fallback branch of the optimization rule didn't track the
dependencies of the join correctly. In particular it didn't mark the LHS
table in the join condition as a dependency when recursing into the LHS
of the join tree. This led to the table being projected out or dropped
in the LHS subtree while still being referenced by the root of the
subtree.

This only happened for bridge tables (tables used to link or bridge
other tables in the join, but whose columns are not referenced in the
final output). If the table was referenced in the output, it would be
included in the list of dependencies from the start and so this bug
would not manifest.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

Added a sql execution test
2026-02-18 20:06:36 +00:00
Jason Larabie f9d4d2748d Small fixes for the Blackholio tutorial (#4343)
# Description of Changes
- Updated the tutorials to use `accessor` in place of `name` for Rust
table definitions
- Removed incorrect file listings for Connect reducer as it's now
private
- Fixed a bug in the Unreal tutorial to bind to correct method for error
handling

# API and ABI breaking changes

N/A

# Expected complexity level and risk
1- Documentation update only

# Testing
- [x] Tested the connect error build for Unreal
- [x] Discovered these issues through manual test of the tutorials
2026-02-18 19:45:16 +00:00
Phoebe Goldman 11ebb7e60a Add migration-focused diagnostics to Rust table macro (#4342)
# Description of Changes

In response to a request by @kim , add diagnostics to our Rust macros
which recognize specific cases we expect to come up when migrating from
1.* to 2.*. More specifically, recognize when a user provides a `name =
my_table` and tell them to change it to an `accessor`.

# API and ABI breaking changes

N/a

# Expected complexity level and risk

1

# Testing

- [x] Compiled outdated private ControlDB and saw improved diagnostics.
2026-02-18 19:43:16 +00:00
Ryan fc6e8fd21d [Docs] Revisions to Chat App doc for 2.0 release (#4335)
# Description of Changes

Updates the Chat App tutorial
`docs/docs/00100-intro/00300-tutorials/00100-chat-app.md`

* TypeScript (React) code snippet fixes
* Updated the initial `App.tsx` snippet to use `import type * as Types
from './module_bindings/types'` and type `systemMessages` as
`Types.Message[]`, matching the current template-generated bindings.
* Updated the placeholder `onlineUsers` / `offlineUsers` types in the
initial snippet to `Types.User[]`.
* Updated the `main.tsx` connection snippet with the template behavior
by sourcing `HOST` / `DB_NAME` from
`import.meta.env.VITE_SPACETIMEDB_HOST` / `VITE_SPACETIMEDB_DB_NAME` if
available.
* Removed an TypeScript example that referenced reducer event wiring
(`conn.reducers.onSendMessage(...)`) that doesn’t exist in the current
TS generated bindings.
* Updated the follow-up instruction text so the “replace `const
onlineUsers: ...`” and “replace `const offlineUsers: ...`” guidance
matches the updated `Types.User[]` placeholders in the earlier snippet.
* The tutorial section says arguments are JSON; the CLI will auto-quote
string args based on reducer parameter types, so the simple form
`send_message 'Hello, World!'` remains valid and is kept.
* Added C# Client SDK step to update `.csproj` file with `net8.0` and a
filter for code in the `spacetimedb` (server module) subdirectory.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

- [x] Performed documented operations locally.
2026-02-18 18:21:55 +00:00
clockwork-labs-bot 0cb23814d3 Fix hash index round-trip through st_indexes (#4336)
## Description of Changes

One-line fix in `system_tables.rs`: when reading indexes back from
`st_index`, `StIndexAlgorithm::Hash` was incorrectly converted to
`BTreeAlgorithm` instead of `HashAlgorithm`.

This caused `check_compatible` to fail with `Index algorithm mismatch`
on **any** republish of a module containing hash indexes — the database
schema would report BTree while the module def specified Hash.
Effectively, any database with a hash index was stuck and could not be
updated.

### Root Cause

`system_tables.rs:1234` in the `From<StIndexAlgorithm> for
IndexAlgorithm` impl:
```rust
// Before (bug — introduced in #3976):
StIndexAlgorithm::Hash { columns } => BTreeAlgorithm { columns }.into(),

// After (fix):
StIndexAlgorithm::Hash { columns } => HashAlgorithm { columns }.into(),
```

The PR that added hash indices (#3976) imported `HashAlgorithm` but used
`BTreeAlgorithm` for the Hash variant conversion.

## API and ABI breaking changes

None.

## Expected complexity level and risk

1 — single word change, restores correct behavior.

## Testing

Existing schema tests cover index round-trips. The bug was caught by
attempting to republish a module with hash indexes.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-02-18 06:14:34 +00:00
Noa 6622e2f975 [TS] better build followup (#4334)
# Description of Changes

Forgot to push something for #4330, whoops. Now it will actually give
the output in that PR.

# Testing

- [x] Already tested.
2026-02-18 04:34:43 +00:00
Jason Larabie 96ba4ea742 Pinning C++ and Unreal to 1.12.0 (#4328)
# Description of Changes
A few small changes to pin the version:
- Updated the CMakeLists back from 2.0.0 to 1.12.0
- Updated the Unreal Blackholio tutorial documentation to target the
1.12.0 branch and not master
- Updated the Unreal Blackholio tutorial to call out 2.0 is coming soon
- Disabled the upgrade-version tool code path for C++ upgrades, but left
logic in place for the near future

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1 - Docs change, config change, and blocking update path for C++

# Testing

- [x] Reviewed the docs
- [x] Tested update command locally
- [x] Tested `spacetime init` for `basic-cpp` and successfully built
2026-02-18 02:46:24 +00:00
Noa 0799becfc5 Improve spacetime build for typescript (#4330)
# Description of Changes

This fixes the confusing error encountered by @gefjon:

```
$ spacetime publish -s local --module-path spacetimedb --no-config event-table-test-ts
Rolldown warning: Could not resolve 'spacetimedb/server' in spacetimedb/src/index.ts
Error: Your module doesn't import the `spacetimedb/server` package at all - this is likely a mistake, as your module will not be able to interface with the SpacetimeDB host.
```
After:
```
[UNRESOLVED_IMPORT] Error: Could not resolve 'spacetimedb/server' in src/index.ts
   ╭─[ src/index.ts:1:47 ]
   │
 1 │ import { schema, table, t, SenderError } from 'spacetimedb/server';
   │                                               ──────────┬─────────  
   │                                                         ╰─────────── Module not found.
   │ 
   │ Help: You may have forgotten to install dependencies with your package manager.
───╯
```

And also runs `tsc`, so that modules with type errors aren't silently
published. Perhaps we want a `--skip-tsc` so that people can run anyway
and get runtime errors?


# Expected complexity level and risk

2

# Testing

- [x] Ensured that tsc and rolldown errors are properly emitted.
2026-02-18 00:02:44 +00:00
Shubham Mishra a0ccf2d1cd Add accessor_name field in ModuleDef (#4323)
# Description of Changes
Update Schema Defs to add `accessor_name` 

Look at `crates/schema/src/def.rs`.
All other file updates are due to changing existing field names.

# API and ABI breaking changes
NA

# Expected complexity level and risk
1
2026-02-17 23:43:17 +00:00
Phoebe Goldman f33188ab1b Minor fixes to examples in event tables document (#4322)
# Description of Changes

Use `accessor =` rather than `name =` in Rust code snippet which defines
event table.

Add `schema` call and `export default` to TypeScript code snippet which
defines event table. I'm not sure this is better, and it's certainly
more cluttered, but the example as written you can't just copy/paste
into your module code.

# API and ABI breaking changes

N/a

# Expected complexity level and risk

Docs only

# Testing

Described elsewhere.
2026-02-17 21:33:31 +00:00
Noa 40d7820002 [TS] Fix ArrayBuilder.{name,default} (#4321)
# Description of Changes

Resolves #4219.

# Expected complexity level and risk

1

# Testing

- [x] Observed that issue is no longer reproducible.
2026-02-17 21:06:31 +00:00
joshua-spacetime 716e18a693 Trigger view refresh when a V8 procedure commits a transaction (#4302)
# Description of Changes

This PR fixes the bug where V8 procedures could commit a transaction
without refreshing affected materialized views, which caused view-backed
subscriptions to miss updates from procedure writes.

# API and ABI breaking changes

None

# Expected complexity level and risk

3

Almost the exact same change as
https://github.com/clockworklabs/SpacetimeDB/pull/4301. The main
difference between the V8 change and the WASM change is that for V8 we
persist the hook functions (`__call_view__`, `__call_view_anon__`, etc.)
and the hook receiver (`recv` / `this`) into V8 context embedder slots,
and reconstruct them later from syscall scope.

# Testing

- [x] Added a regression test in the form of a typescript smoketest that
subscribes to a view and calls a procedure

---------

Co-authored-by: Noa <coolreader18@gmail.com>
2026-02-17 20:49:13 +00:00
Shubham Mishra de2b65fb8d SQL alias (#4304)
# Description of Changes


- [x] : Store "accessor"s names in ModuleDef (for tables, columns, and
indexes for now) and pass them to TableSchema as aliases.

- [x] Create accessor system tables for each of them:
`st_table_accessor`,`st_column_accessor`, `st_index_accessor`

- [x] Update the SQL parsing logic to also consider alias names.



Alias name stored will be same as actual names until we merge
https://github.com/clockworklabs/SpacetimeDB/pull/4263
# API and ABI breaking changes
NA

# Expected complexity level and risk

3

This patch updates SQL name resolution which isn't a very complex change
since table and column name resolution are each handled by their own
helper method.

It also adds new system tables which need to be handle correctly during
restore/replay. We do have regression tests for this that should catch
any incorrect handling or missing steps.

I would say the main risk is that we don't populate cached table and
column schemas with the alias/accessor name. Regression tests have been
added to catch this, but there are edge cases around migrations and
replay that currently aren't covered.

# Testing
 
Added SQL smoketests that use canonical/accessor table/column names.
They currently fail because we're currently using the accessor name for
both. They should pass once this is updated.

---------

Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
2026-02-17 10:15:15 +00:00
clockwork-labs-bot 3e71f4decf Docs: Expand FAQ for 2.0 launch (#4314)
Rewrites the FAQ from 5 basic questions to a comprehensive guide
covering:

- **General** — What is SpacetimeDB, is it only for games, is it
blockchain, licensing, self-hosting
- **Comparisons** — vs Mirror/Photon/networking libs, vs
Firebase/Supabase, vs PostgreSQL
- **Architecture** — Data persistence, real-time sync, reducers vs REST,
module languages, views, procedures
- **Development** — Getting started, `spacetime dev`, SQL usage,
Unity/Unreal/React/framework support, auth
- **Deployment** — Production publishing, hot-swapping modules, schema
migrations, size limits, pricing
- **Troubleshooting** — Global database names (401/403), confusing
generate errors, resetting databases

Content drawn from README, architecture docs, Zen of SpacetimeDB, and
common user questions from GitHub issues and Discord.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-02-17 05:56:47 +00:00
clockwork-labs-bot 8a2208bbcf docs: expand Maincloud deployment page (#4316)
Rewrites the Maincloud deployment guide from a bare-bones stub into a
comprehensive page. Addresses all three points from #3108 plus a
community request for the connection URI.

**New content:**

1. **Finding your module on the dashboard** - Direct URL
(`spacetimedb.com/my-module`) and profile page navigation
2. **Database lifecycle** - Running vs suspended states, automatic
suspension after inactivity, automatic resumption on first request
3. **Next steps section** - Links to dashboard, SpacetimeAuth setup,
quickstart guides, and usage monitoring

**Also added:**
- Prerequisites section (CLI install + `spacetime login` to link web
account)
- Publishing workflow (initial publish, hot-swap updates,
`--delete-data`)
- Client connection code examples for TypeScript, C#, Rust, and C++ with
the Maincloud host URL (`https://maincloud.spacetimedb.com`) - per
community request in #3108
- Database deletion instructions
- Link to pricing page

Closes #3108

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-02-17 05:14:35 +00:00
Ryan e03b7d7516 Updated C# Name attribute to Accessor (#4306)
# Description of Changes

Implementation of #4295

Convert existing `Name` attribute to `Accessor` to support new Canonical
Case conversation of 2.0

# API and ABI breaking changes

Yes, in C# modules, we no longer use the attribute name `Name`, it
should now be `Accessor`

# Expected complexity level and risk

1

# Testing

- [X] Build and tested locally
- [X] Ran regression tests locally
2026-02-17 01:16:16 +00:00
Zeke Foppa 5696089096 Fix metadata version check for 2.0 (#4313)
# Description of Changes

The server upgrade path yells when we upgrade from 1.* to 2.0, but this
upgrade path is confirmed to be good.

# API and ABI breaking changes

None.

# Expected complexity level and risk

2

# Testing

"I" added some unit tests to cover the new cases

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-17 01:02:28 +00:00
Noa fcd9f294e7 Don't call init reducer in spacetime generate (#4312)
# Description of Changes

Fixes #3492.

# Expected complexity level and risk

1

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [ ] <!-- maybe a test you want to do -->
- [ ] <!-- maybe a test you want a reviewer to do, so they can check it
off when they're satisfied. -->
2026-02-16 23:34:19 +00:00
joshua-spacetime 919908fb70 Trigger view refresh when a WASM procedure commits a transaction (#4301)
# Description of Changes

This PR fixes the bug where WASM procedures could commit a transaction
without refreshing affected materialized views, which caused view-backed
subscriptions to miss updates from procedure writes.

The equivalent changes for V8 will be made in a separate patch.

# API and ABI breaking changes

None

# Expected complexity level and risk

3

This was not a simple translation of the reducer code path, because
reducers are run in a single transaction whereas procedures can have
multiple transactions via `with_tx` and views must be refreshed with
each transaction instead of once at the end of the procedure. This
required refresh to be inserted into the syscall itself which required
some extra plumbing. Mainly that we had to attach the validated
`ModuleDef` to the `WasmInstanceEnv`. This should not affect hotswapping
because we instantiate an entirely new `WasmInstanceEnv` in that case.

# Testing

- [x] Added a regression test in the form of a smoketest that subscribes
to a view and calls a procedure
2026-02-16 21:16:35 +00:00
Jeffrey Dallatezza 08ff1e1c11 TS Quickstart: Store different auth tokens for different servers/modules (#3252)
# Description of Changes

In the typescript quickstart example, this includes the server and
module name in the local storage variable name that we use for the auth
token.

This fixes an otherwise annoying issue people run into if they start
running the quickstart locally, then try to run it on maincloud. If they
have already run the app with a local server, their browser will store
the locally signed token, which will get rejected by maincloud.

# Expected complexity level and risk

1.

# Testing

I was able to connect to my local quickstart, then change the variables
to point to a module on maincloud, and I didn't get any errors.

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
v2.0.0-candidate
2026-02-16 16:34:46 +00:00
Shubham Mishra e4098f98d9 Rust: macro change name -> accessor (#4264)
## Description of Changes

This PR primarily affects the `bindings-macro` and `schema` crates to
review:

### Core changes

1. Replaces the `name` macro with `accessor` for **Tables, Views,
Procedures, and Reducers** in Rust modules.
2. Extends `RawModuleDefV10` with a new section for:

   * case conversion policies
   * explicit names
    New sections are not validated in this PR so not functional.
3. Updates index behavior:

* Index names are now always **system-generated** for clients. Which
will be fixed in follow-up PR when we start validating RawModuleDef with
explicit names.
   * The `accessor` name for an index is used only inside the module.


## Breaking changes (API/ABI)

1. **Rust modules**

   * The `name` macro must be replaced with `accessor`.

2. **Client bindings (all languages)**

* Index names are now system-generated instead of using explicitly
provided names.


**Complexity:** 3

A follow-up PR will reintroduce explicit names with support for case
conversion.

---------

Co-authored-by: rekhoff <r.ekhoff@clockworklabs.io>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
2026-02-16 15:23:50 +00:00
Julien Lavocat 83851fe9df Add Angular integration (#4139)
# Description of Changes

- Add Angular integration
- Add Angular quickstart chat template

# API and ABI breaking changes

None.

# Expected complexity level and risk

2

# Testing

Ran the template

---------

Co-authored-by: Tien Pham <tien@clockworklabs.io>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-02-16 02:21:52 +00:00
Piotr Sarnacki 4c962b9170 spacetime.json config implementation (#4199)
# Description of Changes

This PR implements support for the `spacetime.json` configuration file
that can be used to set up common `generate` and `publish` targets. An
example of `spacetime.json` could look like this:

```
{
  "dev_run": "pnpm dev",
  "generate": [
    { "out-dir": "./foobar", "module-path": "region-module", "language": "c-sharp" },
    { "out-dir": "./global", "module-path": "global-module", "language": "c-sharp" },
  ],
  "publish": {
    "database": "bitcraft",
    "module-path": "spacetimedb",
    "server": "local",
    "children": [
      { "database": "region-1", "module-path": "region-module", server: "local" },
      { "database": "region-2", "module-path": "region-module", server: "local" }
    ]
  }
}
```

With this config, running `spacetime generate` without any arguments
would generate bindings for two targets: `region-module` and
`global-module`. `spacetime publish` without any arguments would publish
three modules, starting from the parent: `bitcraft`, `region-1`, and
`region-2`. On top of that, the command `pnpm dev` would be executed
when using `spacetime dev`.

It is also possible to pass additional command line arguments when
calling the `publish` and `generate` commands, but there are certain
limitations. There is a special case when passing either a module path
to generate or a module name to publish. Doing that will filter out
entries in the config file that do not match. For example, running:

```
spacetime generate --project-path global-module
```

would only generate bindings for the second entry in the `generate`
list.

In a similar fashion, running:

```
spacetime publish region-1
```

would only publish the child database with the name `region-1`

Passing other existing arguments is also possible, but not all of the
arguments are available for multiple configs. For example, when running
`spacetime publish --server maincloud`, the publish command would be
applied to all of the modules listed in the config file, but the
`server` value from the command line arguments would take precedence.
Running with arguments like `--bin-path` would, however, would throw an
error as `--bin-path` makes sense only in a context of a specific
module, thus this wouldn't work: `spacetime publish --bin-path
spacetimedb/target/debug/bitcraft.wasm`. I will throw an error unless
there is only one entry to process, thus `spacetime publish --bin-path
spacetimedb/target/debug/bitcraft.wasm bitcraft` would work, as it
filters the publish targets to one entry.

# API and ABI breaking changes

None

# Expected complexity level and risk

3

The config file in itself is not overly complex, but when coupled with
the CLI it is somewhat tricky to get right. There are also some changes
that I had to make to how clap arguments are validated - because the
values can now come from both the config file and the clap config, we
can't use some of the built-in validations like `required`, or at least
I haven't found a clean way to do so.

# Testing

I've added some automated tests, but more tests and manual testing is
coming.

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: bradleyshep <148254416+bradleyshep@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
2026-02-15 23:22:44 +00:00