Commit Graph

267 Commits

Author SHA1 Message Date
clockwork-labs-bot 478967afff Add release tooling (#5325)
# Description of Changes

Adds release tooling under `tools/release` and a manual release workflow
at `.github/workflows/release.yml`.

The release workflow can run the existing release targets for crates.io
packages, the TypeScript SDK, C# SDK, C++ bindings, Docker images, and
the S3 mirror latest-version marker.

# API and ABI breaking changes

None.

# Expected complexity level and risk

2. This moves existing release automation into this repository and
updates paths that previously assumed a nested checkout layout. The main
risk is GitHub Actions wiring and secret availability during a real
release.

# Testing

- [x]
`PATH=/Users/clockworklabs/.rustup/toolchains/1.93.0-aarch64-apple-darwin/bin:$PATH
cargo fmt --all`
- [x]
`PATH=/Users/clockworklabs/.rustup/toolchains/1.93.0-aarch64-apple-darwin/bin:$PATH
cargo check -p spacetimedb-release`
- [x]
`PATH=/Users/clockworklabs/.rustup/toolchains/1.93.0-aarch64-apple-darwin/bin:$PATH
cargo run -q -p spacetimedb-release -- release --help`
- [x] Ruby YAML parse for `.github/workflows/release.yml`
- [x] `git diff --check`

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-28 19:39:53 +00:00
joshua-spacetime 41d935bb10 Make keynote bench job reusable (#5433)
# Description of Changes

Makes the keynote benchmark job reusable so that it can be invoked and
run in other CI environments.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

2

# Testing

Refactor. Relies on existing coverage.
2026-06-25 13:52:29 +00:00
joshua-spacetime 963bec1d6f Remove spacetimedb-jsonwebtoken and spacetimedb-jwks dependencies (#5427)
# Description of Changes

Uses `jsonwebtoken v10.4.0` instead. Important changes include:

**1. Token serialization**
Old tokens with `"exp": null` are still accepted, but new no-expiry
tokens now omit `exp` instead of serializing it as `"exp": null`.

**2. OIDC/JWKS validation**
Issuer extraction now uses `jsonwebtoken::dangerous::insecure_decode`
for key discovery only, not validation. And the old `spacetimedb-jwks`
crate required every JWK to have a `kid`, but this patch does not
preserve that limitation.

# API and ABI breaking changes

I don't believe this is considered breaking, but it bears repeating that
new no-expiry tokens now serialize without `exp` instead of `"exp":
null`.

# Expected complexity level and risk

2

# Testing

- [x] Verify a legacy no-expiry token serialized as `"exp": null` still
validates.
- [x] Verify a token with an expired `exp` is still rejected.
- [x] Verify OIDC/JWKS validation works when the JWKS keys omit the
optional `kid` field.
2026-06-23 22:56:59 +00:00
Ryan a08663c7b9 Version bump 2.7.0 (#5399)
# Description of Changes

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

- Bumps version to 2.7.0

# API and ABI breaking changes

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

None

# Expected complexity level and risk

- 1 - this is just a version bump

<!--
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] Version number is correct (`2.7.0`)
- [x] BSL license file has been updated with the new date and version
number
2026-06-22 04:08:56 +00:00
Shubham Mishra 77ffdbbe18 Move RelationalDB to spacetimedb-engine crate. (#5113)
# Description of Changes

Moves `RelationalDB` and related database code into a new
`spacetimedb-engine` crate.
The main motivation is to tighten dependency control around the engine
layer and isolate `RelationalDB`
 behind a crate boundary.
  - Majority of this PR is code-motion.
- Removes direct production dependence on `tokio` from
`spacetimedb-engine`.
- Keeps `tokio` only as a dev-dependency for test-only code in
`spacetimedb-engine`.
- This is intended to be a structural refactor only and should not
result in any functional change in
  production.
- Adds a CI check to ensure `spacetimedb-engine` continues to compile in
simulation mode

# API and ABI breaking changes
NA

# Expected complexity level and risk
1.5.

# Testing
Existing tests should be enough.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-16 16:16:13 +00:00
Ryan 31fd1c8c33 Version bump 2.6.0 (#5326)
# Description of Changes

* Bump version to 2.6.0

# API and ABI breaking changes

None

# Expected complexity level and risk

* 1 - this is just a version bump

# Testing

- [X] Version number is correct (`2.6.0`)
- [X] BSL license file has been updated with the new date and version
number
2026-06-16 01:11:36 +00:00
Zeke Foppa 4ca987e250 Remove cargo bump-versions (#5157)
# Description of Changes

(Moving this to a tools repo)

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

None

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-10 19:07:22 +00:00
Ryan 0abf20b959 Bump version to 2.5.0 (#5258)
# Description of Changes

Bump version to `2.5.0` for new release

# API and ABI breaking changes

N/A

# Expected complexity level and risk

1

# Testing

None
2026-06-10 02:56:58 +00:00
Phoebe Goldman 4c8ce71c38 Add some tests of procedure concurrency (#4955)
# Description of Changes

Add several new tests of concurrency behavior re: procedures.

The new tests are in the SDK tests, 'cause I thought the easiest way to
observe this behavior was by connecting a client to a database and
calling some functions in it. This is yet another mild misuse of the SDK
test suite, as the behavior in question is not in the SDK, it's in the
host. The tests also have a new module/client pair added, as we don't
(yet?) expose `procedure_sleep_until` to any module languages other than
Rust, so we can't implement the same test in any other languages.

### `procedure_reducer_interleaving`

Verifies that a procedure and a reducer can run concurrently, with the
procedure cooperatively yielding using `ctx.sleep_until`. Uses two
separate connections due to #4954 .

### `procedure_reducer_same_client_interleaved`

Same as previous, but with only a single connection. Now that #4954 is
closed, this has the same semantics as previous.

### `procedure_concurrent_with_scheduled_reducer`

Verifies that a non-scheduled procedure can schedule a reducer and then
sleep, and the reducer will execute before the procedure wakes back up.

### `scheduled_procedure_scheduled_reducer_not_interleaved`

Schedules a procedure and a reducer, which you might expect to execute
concurrently, but don't in a way similar to
`procedure_reducer_same_client_not_interleaved`.

This is the behavior that kicked off this whole thing. The scheduler
subsystem behaves like a single client, in the sense that it waits for a
single function to terminate before scheduling the next function.

# API and ABI breaking changes

N/a

# Expected complexity level and risk

1 - tests

# Testing

- [x] Ran the tests!

I didn't bother intentionally breaking the host to verify that the tests
would fail. It feels pretty apparent to me based on just the test code
that we won't see false negatives.
2026-06-09 20:19:55 +00:00
joshua-spacetime eef0e423a8 Add primary key support for procedural views to rust and ts modules (#5111)
# Description of Changes

Adds support for primary keys to procedural views in rust and typescript
modules. Now clients can receive update events when subscribed to such
views.

```rust
#[spacetimedb::view(accessor = my_players, public, primary_key = id)]
pub fn my_players(ctx: &spacetimedb::ViewContext) -> Vec<Player> {
    ctx.db.players().owner().filter(ctx.sender()).collect()
}
```

```ts
const Player = t.row('Player', {
  id: t.u64().primaryKey(),
  owner: t.identity().index('btree'),
  name: t.string(),
});

export const my_players = spacetimedb.view(
  { public: true },
  t.array(players.rowType),
  ctx => Array.from(ctx.db.players.owner.filter(ctx.sender))
);
```

In rust, a view's primary key is declared within the `#[view]` macro,
whereas in typescript it is declared at the column/row level as it is
for tables. I could have made it a view level attribute for typescript
as well, but since primary keys are already row-level attributes in
typescript, I just kept that as is.

Note, care must be taken to ensure that the view never returns duplicate
primary keys, or else it will fail which will currently result in the
transaction that triggered the view refresh to be rolled back. Better
error handling for this exact scenario will be added in a separate
follow up patch.

## Alternative Considered: #[primary_key] attribute on `SpacetimeType`s
in Rust

This would be equivalent to what we do in typescript.

# API and ABI breaking changes

None, although adding a primary key to an existing view will require a
client update.

# Expected complexity level and risk

3

# Testing

Compile-time failure scenarios:
- [x] Primary key on non-existent column
- [x] Primary key doesn't reference custom accessor name (rust)
- [x] Multiple primary key columns specified (typescript)
- [x] Primary keys must be `FilterableValue`s

SDK tests (rust sdk, rust and ts modules):
- [x] `OnUpdate`
- [x] `OnUpdate` is sender-scoped
- [X] Can join on primary key columns

Smoketests:
- [x] Modifying primary key columns breaks clients (auto-migrations)
2026-06-04 18:44:58 +00:00
Shubham Mishra 0be66e3e3d Deterministic runtime crate (#5016)
# Description of Changes.

Introduces deterministic runtime crate.
Integrate it with RelationalDB.

I think best steps to review:
- Read the
[README](https://github.com/clockworklabs/SpacetimeDB/blob/shub/sim/crates/runtime/README.md)
of runtime crate.
- Look at the integration with existing crates - `durability`, `core`,
`snapshot`, etc.
- Read runtime crate's code.

Draft branch to Test code -
https://github.com/clockworklabs/SpacetimeDB/pull/5019

# API and ABI breaking changes
NA

# Expected complexity level and risk
Does not intend to change any production functionality, but it's big
code.

# Testing

- new crate contains unit and integration tests.
- Existing tests should work for production.

---------

Signed-off-by: Shubham Mishra <shivam828787@gmail.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-04 14:59:37 +00:00
Zeke Foppa 10ebb2ba42 Bump versions to 2.4.1 (#5216)
# Description of Changes

In preparation for upcoming release.

**This only bumps the Rust+CLI versions**

# API and ABI breaking changes

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

# Expected complexity level and risk

<!--
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

existing CI

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-06-04 04:28:06 +00:00
Muhammad Amin Saffari Taheri d16f824217 Add SolidJS integration with docs quickstart (#5052)
# Description of Changes

This PR adds support for Solid.
Related issue: https://github.com/clockworklabs/SpacetimeDB/issues/4820

The initial implementation was with an LLM, since Solid and React are
very similar. Then I improved on it.
The docs though are completely written by the LLM, I just read through
them once to make sure there aren't any problems.

# API and ABI breaking changes

There are no API or ABI changes. Just added support for Solid.

# Expected complexity level and risk

I'd say around 1 or 2. I haven't tested it too much except for the
example that I added.

# Testing

I'll be testing it more with the test app I'm planing to build.
- [ ] I've added the test solid router similar to test react router, and
it was working, but it'll be nice if someone else can verify as well.
- [ ] I'll be testing it more with the test app I'm planing to build

---------

Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-03 22:23:36 +00:00
Ryan b3547448cf Version bump 2.4.0 (#5162)
# Description of Changes

* Bumps version to 2.4.0

# API and ABI breaking changes

None

# Expected complexity level and risk

* 1 - this is just a version bump

# Testing

- [X] Version number is correct (`2.4.0`)
- [X] BSL license file has been updated with the new date and version
number

---------

Signed-off-by: Ryan <r.ekhoff@clockworklabs.io>
2026-06-02 18:08:43 +00:00
Zeke Foppa 0305a24fdc Bump versions to 2.3.0 (#5120)
# Description of Changes

Bump version numbers to 2.3.0 in preparation for an upcoming release

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing
CI 🤷

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-05-26 18:25:12 +00:00
clockwork-labs-bot d3b4a96132 Drop serde_json arbitrary_precision from workspace (#5001)
Closes #4989

We were not using `arbitrary_precision` in the workspace: I only found
the workspace dependency declaration itself plus a normal
`serde_json::Number::from(3u8)` call in
`crates/cli/src/spacetime_config.rs`, which does not require the
feature.

## Summary
- remove `serde_json/arbitrary_precision` from the workspace dependency
declaration
- keep `raw_value`, which is the only serde_json feature the workspace
is clearly using here
- avoid forcing a non-additive serde_json feature onto downstream
consumers via feature unification

## Validation
- `cargo tree -e features -p serde_json`
- `cargo check -p spacetimedb-sdk -p spacetimedb-lib -p spacetimedb-sats
-p spacetimedb-schema`

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-05-21 19:13:29 +00:00
Jeff Rooks 93a68ade00 chore: enable HTTP/2 support for backend server (#5027)
# Description of Changes

Enables Axum's `http2` feature for SpacetimeDB, which enables Hyper's
HTTP/2 support in the standalone/backend HTTP server.

This allows clients that explicitly speak cleartext HTTP/2 (`h2c`) to
connect to the local standalone server over HTTP/2.

_Note: public HTTPS deployments may also require edge proxy or load
balancer configuration, such as enabling HTTP/2 ALPN on nginx. For
example, `curl --http2 -v https://maincloud.spacetimedb.com/v1/ping`
currently negotiates `http/1.1` at the public edge._


Refs #4964

# API and ABI breaking changes

None.

# Expected complexity level and risk

1

This is a dependency feature flag change. It should not affect existing
HTTP/1.1 clients, and the server continues to accept HTTP/1.1 requests.

# Testing

- Build the standalone server: `cargo build -p spacetimedb-standalone`
- Start the local standalone server and verify HTTP/2 cleartext prior
knowledge support: `cargo run -p spacetimedb-standalone -- start
--data-dir /tmp/spacetimedb-data --jwt-key-dir /tmp/spacetimedb-data
--listen-addr 127.0.0.1:3000 --in-memory --non-interactive`
- Test using curl http prior knowledge flag with the local instance:
`curl --http2-prior-knowledge -v http://127.0.0.1:3000/v1/ping`

**Output**
```bash
*   Trying 127.0.0.1:3000...
* Established connection to 127.0.0.1 (127.0.0.1 port 3000) from 127.0.0.1 port 42662
* using HTTP/2
* [HTTP/2] [1] OPENED stream for http://127.0.0.1:3000/v1/ping
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: http]
* [HTTP/2] [1] [:authority: 127.0.0.1:3000]
* [HTTP/2] [1] [:path: /v1/ping]
* [HTTP/2] [1] [user-agent: curl/8.20.0]
* [HTTP/2] [1] [accept: */*]
> GET /v1/ping HTTP/2
> Host: 127.0.0.1:3000
> User-Agent: curl/8.20.0
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
< vary: origin, access-control-request-method, access-control-request-headers
< access-control-allow-origin: *
< content-length: 0
< date: Fri, 15 May 2026 10:25:12 GMT
<
* Connection #0 to host 127.0.0.1:3000 left intact
```
2026-05-21 17:56:04 +00:00
Zeke Foppa 8df7df3270 cargo ci dlls -> cargo regen csharp dlls (#4972)
# Description of Changes

Just moving this command in preparation to create a lot more `cargo
regen` commands.

- `master`
  - **[This PR] `cargo ci dlls` -> `cargo regen csharp dlls`**
- [#4971 Translate some bash scripts to
Rust](https://github.com/clockworklabs/SpacetimeDB/pull/4971)
- [#4921 CI - `cargo test` runs C# and TypeScript
tests](https://github.com/clockworklabs/SpacetimeDB/pull/4921)
- [#4948 CI - Run unity tests through `cargo
test`](https://github.com/clockworklabs/SpacetimeDB/pull/4948)

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

- [x] CI still passes

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-05-08 12:48:22 +00:00
joshua-spacetime 1f0e1271a8 Pipeline js module operations (#4962)
# Description of Changes

The core motivation for this change is simple: avoid cross-thread
handoffs and synchronization on the main execution path.

Before this change, the ingress task for each websocket connection would
wait for a completion response on each request before submitting the
next request to the database. This was mainly used to guarantee that we
delivered message responses in receive-order per connection. However it
also meant that for every request, we notified a waiting Tokio task,
which potentially incurred kernel-assisted wakeup and scheduler
overhead.

Note this design existed mainly for historical reasons. Before the
database had a dedicated job thread, requests were not serialized
through a single queue. The module instance was gated behind a semaphore
which guaranteed mutual exclusion, but it did not guarantee FIFO
ordering. Awaiting the completion of each request in `ws_recv_task` was
therefore the mechanism that enforced per-connection receive-order
semantics. However it now serves primarily as a source of overhead.

Procedures are the important exception. They are not serialized through
the main worker queue. Instead they use their own instance pool so as to
be able to run concurrently with other requests. However procedures may
be composed of multiple transactions and they may effectively yield
between transactions. This means that before this change, if a procedure
were to yield, it would effectively block all subsequent requests from
that client until it returned which is quite undesirable.

So with this change, procedures may execute out of order with other
operations received on the same WebSocket. Hence if this is not a
desirable property, clients must enforce ordering themselves by waiting
for a response before submitting the next request.

## What changed?

### 1. Different instance managers for procedures and everything else

Procedures use a bounded instance pool where each instance is backed by
an isolate running in a thread. Reducers and all other operations are
serialized through an mpsc queue that feeds a single isolate running in
a thread.

Trapped isolates are replaced inline. Only a fatal error within one of
the instance threads results in the `ModuleHost` and all its connections
being dropped. The host controller will recreate a new `ModuleHost`
lazily on the next request.

### 2. New enqueue-only `ModuleHost` interface

`ClientConnection` now calls enqueue-only methods on `ModuleHost` which
return immediately after enqueuing on the main instance lane or in the
case of a procedure, checking out an available instance and starting the
operation.

### 3. Separate `ModuleHost` interfaces for scheduled reducers and
scheduled procedures

Scheduled reducers now target the main js instance/worker, while
scheduled procedures go through the pool. The scheduler now
distinguishes between reducers and procedures and calls the appropriate
method.

Note, the scheduler does not pipeline its operations. It waits for each
one to complete before scheduling the next operation. This means that a
long running procedure will block all other operations from being
scheduled. This will need to be fixed at some point, but this patch
doesn't change the current behavior.

### 4. Misc

This patch also names the main js worker thread for better diagnostics.
It also disables core pinning by default and makes it an explicit
opt-in.

This last one is pretty important. The current architecture reduces
thread and context switching significantly such that naive core pinning
may perform worse than just deferring to the OS scheduler on certain
platforms. As it stands, the main motivation which led us to our
original core pinning strategy no longer exists, so we should probably
just defer to the OS until we've designed a proper scheduler that suits
our needs.

# API and ABI breaking changes

As mentioned above, with this change, procedures may execute out of
order with other operations received on the same WebSocket. Hence if
this is not a desirable property, clients must enforce ordering
themselves by waiting for a response before submitting the next request.

# Expected complexity level and risk

4

# Testing

This is mainly a performance oriented refactor, so no additional
correctness tests were added. However this patch does touch a lot of
code that could probably use more coverage in general. Benchmarks were
run to verify expected performance characteristics.

---------

Signed-off-by: joshua-spacetime <josh@clockworklabs.io>
Co-authored-by: Noa <coolreader18@gmail.com>
2026-05-07 01:29:32 +00:00
John Detter eb11e2f5c4 Version bump 2.2.0 (#4916)
# Description of Changes

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

- Bumps version to 2.2.0

# API and ABI breaking changes

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

None

# Expected complexity level and risk

- 1 - this is just a version bump

<!--
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] Version number is correct (`2.2.0`)
- [x] BSL license file has been updated with the new date and version
number

---------

Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-30 19:24:41 +00:00
Shubham Mishra 7332ece680 Case conversion tests (#4450)
# Description of Changes

Tests for case conversion.

# API and ABI breaking changes

NA

# Expected complexity level and risk

1

---------

Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-04-30 09:00:13 +00:00
Zeke Foppa 70db721c3a Revert breaking PRs (#4881)
# Description of Changes

Revert the following PRs that have caused some breakage:
```
a32cffa76 Finish refactoring out replay (#4850)
d639be0af Replay: some code motion & reuse `ReplayCommittedState` (#4849)
78d6b6f7d Update NativeAOT-LLVM infrastructure to current ABI (#4515)
d5c1738c1 Better module backtraces for panics and whatnot (#577)
6f23b19f3 Wait for database update to become durable (#4846)
81c9eab86 Add `spacetime lock/unlock` to prevent accidental database deletion (#4502)
809aebd7c Move field `replay_table_updated` to `ReplayCommittedState` (#4807)
21b58ef99 Update axum (#2713)
b5cadff7a Extract replay stuff out of `CommittedState`, part 1 (#4804)
```

I also updated the Python smoketests for breakage introduced in
https://github.com/clockworklabs/SpacetimeDB/pull/4502. Reverting that
PR caused conflicts, so this fix is more straightforward.

# API and ABI breaking changes

Maybe kind of, but we haven't released any of these.

# Expected complexity level and risk

1

# Testing

Ask @bfops about testing

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-23 14:54:23 -07:00
Noa 21b58ef993 Update axum (#2713)
# Description of Changes

~~Axum now has what we need out of it for a websocket wrapper, so we no
longer need to duplicate `util/flat_csv.rs` and `util/websocket.rs`,
meaning we have less code to maintain.~~ Nevermind, we know send raw
frames, which axum's wrapper does not support. Makes this PR simpler.

# Expected complexity level and risk

2 - upgrading a dependency is a risk, but looking through the
[changelog](https://github.com/tokio-rs/axum/blob/main/axum/CHANGELOG.md#080)
there isn't anything that should affect us.

# 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] tests pass <!-- 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. -->

Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
2026-04-16 13:08:25 +00:00
Kim Altintop 2b3aa5ae26 durability: Use async-channel to allow blocking send (#4802)
The previous approaches would either:

- panic when the queue becomes full, as `append_tx` is run inside the
context of a `LocalSet`, which is basically a glorified current thread
runtime
- deadlock because the receiver runtime has no way of notifiying the
sender of freed capacity in the channel

`async-channel` handles wait queues and notifications internally, so can
be used freely from either blocking or async contexts.

This _may_ come at different performance characteristics, but I haven't
measured them.

---------

Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
2026-04-14 20:12:51 +00:00
joshua-spacetime 29a9d063a3 Remove rust client from keynote bench (#4753)
# Description of Changes

We only benchmark the typescript module and sdk now.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

N/A
2026-04-07 18:57:59 +00:00
Zeke Foppa 480fd5841a Bump versions to 2.1.0 (#4681)
# Description of Changes

Bump versions to 2.1.0

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing
CI

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-03-20 21:53:51 +00:00
joshua-spacetime 047dac9745 Remove legacy SQL code (#4628)
# Description of Changes

This patch removes the dead legacy SQL query engine and the remaining
code that only existed to support it.

Removed:

- Old SQL compiler/type-checker and VM-based execution path in
spacetimedb-core
- `spacetimedb-vm` crate
- Dead vm specific error variants and compatibility code
- Obsolete tests, benchmarks, and config paths that still referenced the
legacy engine

Small pieces still used by the current engine were moved to their proper
homes instead of keeping the `vm` crate around. In particular,
`RelValue` was moved to `spacetimedb-execution`.

The `sqltest` crate was also updated to use the current engine. Notably
though these tests are not run in CI, however I've kept them around as
they may be beneficial as we look to expand our SQL support in the
future.

Requires codeowner review from @cloutiertyler due to the removal of the
`LICENSE` file in the (now removed) `vm` crate.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

None

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-03-19 17:47:00 +00:00
Ning Sun 44c4b2a4aa feat: update pgwire to 0.37 (#3910)
# Description of Changes

Update pgwire to 0.37

Make `DataRowEncoder` reusable as enabled in this release, make
introduce 3x performance on encoding.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

N/A

# 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. -->

---------

Signed-off-by: Ning Sun <sunning@greptime.com>
Signed-off-by: joshua-spacetime <josh@clockworklabs.io>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-03-19 16:50:28 +00:00
John Detter cf06f8ad3c Version bump to 2.0.5 (#4623)
# Description of Changes

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

- Bumps version to 2.0.5

# API and ABI breaking changes

None - this is just a version bump

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

# Expected complexity level and risk

1 - just a version bump

<!--
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] License file has been properly updated, including the date change
- [x] CI is passing other than the internal check
2026-03-12 21:03:37 +00:00
Simon Gellis 18d4fbc320 Upgrade prometheus to 0.14.0 (#4598)
# Description of Changes

Upgrades the rust SDK's prometheus dependency from 0.13 to 0.14.

Fixes https://github.com/clockworklabs/SpacetimeDB/issues/4597

# API and ABI breaking changes

[The prometheus
changelog](https://github.com/tikv/rust-prometheus/blob/master/CHANGELOG.md#0140)
claims that the MSRV for the new version is 1.82, but this project
doesn't seem to have an official MSRV, so I don't think that's an ABI
change.

I don't think depending on a different prometheus version is itself a
breaking change. Prometheus is exposed through the rust SDK, but in an
explicitly [unstable
module](https://github.com/clockworklabs/SpacetimeDB/blob/3f58b5951bf3c49971c51aecb526439597b9c044/sdks/rust/src/lib.rs#L69-L76)
which "may change incompatibly without a major version bump". Prometheus
structs are also exposed from several crates, but with the same
disclaimers about unstable interfaces.

# Expected complexity level and risk

1. This is a module bump with simple-looking changes.

# Testing

- [x] Just confirmed everything still compiles and the tests still pass

Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-03-11 21:58:35 +00:00
joshua-spacetime 6eaf06b6b5 [Rust] Primary keys for query builder views (#4572)
# Description of Changes

Query builder views return a subset of rows from a physical table. If
that table has a primary key, then so should the view. What this means
concretely is that the view should expose the same api as the table,
specifically as it relates to the primary key column.

With that in mind, this patch commits the following changes:
1. Annotates `ViewDef` with a `primary_key`
2. Updates the return type of query builder views in the raw module def
to a special product type
3. Adds an index for the primary key on the view's backing table
4. Updates the query planner to use this index
5. Updates rust client codegen to generate `on_update` for such views

# API and ABI breaking changes

None

Old `impl Query` views compiled with an older version of SpacetimeDB
will continue to work as they did before - without a primary key.

# Expected complexity level and risk

3

# Testing

- [x] New rust sdk integration suite exercising `on_update` for PK views
and semijoin scenarios
- [x] Smoketests for PK views and semijoin scenarios
2026-03-11 13:00:43 +00:00
John Detter 354dd45499 Version bump 2.0.4 (#4600)
# Description of Changes

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

- Bumps version to 2.0.4

# API and ABI breaking changes

None - this is just a version bump

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

# Expected complexity level and risk

1 - this is just a version bump

<!--
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] License file has been updated with correct version + time

---------

Signed-off-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-03-10 18:37:47 +00:00
Noa e3582131fe Migrate to Rust 2024 (#3802)
# Description of Changes

It'd be best to review this commit-by-commit, and using
[difftastic](https://difftastic.wilfred.me.uk) to easily tell when
changes are minor in terms of syntax but a line based diff doesn't show
that.

# Expected complexity level and risk

3 - edition2024 does bring changes to drop order, which could cause
issues with locks, but I looked through [all of the warnings that
weren't fixed
automatically](https://gistcdn.githack.com/coolreader18/80485ae5c5f82de1784229cce2febb26/raw/ba80f3fecda66ceb34f4f7ad73b98ea02d4893a2/warnings.html)
and couldn't find any issues.

# Testing

n/a; internal code change
2026-03-03 11:06:52 +00:00
John Detter c29a44c50b Version upgrade 2.0.3 (#4489)
# Description of Changes

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

- Version upgrade 2.0.3

# API and ABI breaking changes

- None, this is a version bump

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

# Expected complexity level and risk

- 1 - this is a version bump

<!--
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] License has been updated
- [x] Version number is correct (2.0.3)
2026-02-27 20:24:22 +00:00
Zeke Foppa 1e6aa3226c Bump versions to 2.0.2 (#4455)
# Description of Changes

Bumping all versions to 2.0.2 for the release.

# API and ABI breaking changes

None.

# Expected complexity level and risk

1

# Testing

CI

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-26 01:54:35 +00:00
Mazdak Farrokhzad 6832fa1bce keynote-2: use rust client (#4421) 2026-02-24 17:47:20 +01:00
Zeke Foppa 88407f0958 Bump versions to 2.0.1 (#4403)
# Description of Changes

Just bumping versions to 2.0.1.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing
- [ ] CI passes

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-23 21:54:10 +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 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
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
Tyler Cloutier 3f58b5951b Implement event tables (server, Rust/TS/C# codegen + client SDKs) (#4217)
## Summary

Implements event tables end-to-end: server datastore, module bindings
(Rust/TypeScript/C#), client codegen (Rust/TypeScript/C#), client SDKs
(Rust/TypeScript/C#), and integration tests.

Event tables are tables whose rows are ephemeral — they persist to the
commitlog and are delivered to V2 subscribers, but are NOT merged into
committed state. Rows are only visible within the transaction that
inserted them. This is the mechanism that replaces reducer event
callbacks in 2.0.

## What's included

### Server
- `is_event` flag on `RawTableDefV10`, `TableDef`, `TableSchema`
- Event table rows recorded in TxData but skipped during committed state
merge
- Commitlog replay treats event table inserts as no-ops
- Migration validation rejects changing `is_event` between module
versions
- `SELECT * FROM *` excludes event tables
- V1 WebSocket subscriptions to event tables rejected with upgrade
message
- V2 subscription path delivers event table rows correctly
- `CanBeLookupTable` trait — event tables cannot be lookup tables in
semijoins
- Runtime view validation rejects event tables

### Module bindings
- **Rust**: `#[spacetimedb::table(name = my_events, public, event)]`
- **TypeScript**: `table({ event: true }, ...)`
- **C#**: `[Table(Event = true)]`

### Client codegen (`crates/codegen/`)
- **Rust**: Generates `EventTable` impl (insert-only) for event tables,
`Table` impl for normal tables. `CanBeLookupTable` emitted for non-event
tables.
- **TypeScript**: Emits `event: true` in generated table schemas.
`ClientTableCore` type excludes `onDelete`/`onUpdate` for event tables
via conditional types.
- **C#**: Generates classes inheriting from `RemoteEventTableHandle`
(which hides `OnDelete`/`OnBeforeDelete`/`OnUpdate`) for event tables.

### Client SDKs
- **Rust**: `EventTable` trait with insert-only callbacks, client cache
bypass, `count()` returns 0, `iter()` returns empty
- **TypeScript**: Event table cache bypass in `table_cache.ts` — fires
`onInsert` callbacks but doesn't store rows. Type-level narrowing
excludes delete/update methods.
- **C#**: `RemoteEventTableHandle` base class hides delete/update
events. Parse/Apply/PostApply handle `EventTableRows` wire format, skip
cache storage, fire only `OnInsert`.

### Tests
- 9 datastore unit tests (insert/delete/update semantics, replay,
constraints, indexes, auto-inc, cross-tx reset)
- 3 Rust SDK integration tests (basic events, multiple events per
reducer, no persistence across transactions)
- Codegen snapshot tests (Rust, TypeScript, C#)
- Trybuild compile tests (event tables rejected as semijoin lookup
tables)

## Deferred
- `on_delete` codegen for event tables (server only sends inserts;
client synthesis deferred)
- Event tables in subscription joins / views (well-defined but
restricted for now)
- C++ SDK support
- RLS integration test

## API and ABI breaking changes

- `is_event: bool` added to `RawTableDefV10` (appended, defaults to
`false` — existing modules unaffected)
- `CanBeLookupTable` trait bound on semijoin methods in query builder
(all non-event tables implement it, so existing code compiles unchanged)
- `RemoteEventTableHandle` added to C# SDK (new base class for generated
event table handles)

## Expected complexity level and risk

3 — Changes touch the schema pipeline end-to-end and all three client
SDKs, but each individual change is straightforward. The core risk area
is the committed state merge skip in `committed_state.rs`. Client SDK
changes are additive (new code paths for event tables, existing paths
unchanged).

## Testing

- [x] `cargo clippy --workspace --tests --benches` passes
- [x] `cargo test -p spacetimedb-codegen` (snapshot tests)
- [x] `cargo test -p spacetimedb-datastore --features
spacetimedb-schema/test -- event_table` (9 unit tests)
- [x] `pnpm format` passes
- [x] Rust SDK integration tests pass (`event_table_tests` module)

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
2026-02-15 22:56:20 +00:00
John Detter 50295ac865 Version upgrade to 2.0 (#4252)
# Description of Changes

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

- Version upgrade to 2.0.

# API and ABI breaking changes

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

# Expected complexity level and risk

1 - this is just a version bump

<!--
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] License file has been updated
- [x] CI passing

---------

Signed-off-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-02-12 16:25:49 +00:00
Noa 253095aab5 Bump rolldown to 1.0.0-rc.3 (#4259)
# Description of Changes

Rolldown likely [won't release 1.0 until after vite
8.0](https://voidzero.dev/posts/announcing-rolldown-rc), but I figure we
should keep up to date somewhat and switch from the beta to the rc.

# Expected complexity level and risk

1

# Testing

- [x] `spacetime build` with typescript modules still works.

---------

Signed-off-by: Noa <coolreader18@gmail.com>
2026-02-12 09:01:39 +00:00
Noa 7677b5478f [TS] Export reducers, etc from a module (#4220)
# Description of Changes

Haven't changed `schema()` to accept an object yet, maybe that's for a
followup?

Now everything exported from the module must be exported from the
typescript module.

# Expected complexity level and risk

<!--
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! -->

- [ ] <!-- 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-11 22:45:36 +00:00
Noa 87d875944a [TS] Bundle ICU data (#4253)
# Description of Changes

Fixes #3926. This PR bundles in icudata (11MB) to the spacetime binary,
to allow i18n functions like `String.prototype.localeCompare()` to work.
The 2nd commit sets the default locale to [en-001, "International
English"](https://www.ctrl.blog/entry/en-001.html), in order to prevent
system locale from affecting the execution of reducers.

# Expected complexity level and risk

1

# Testing

- [x] Verify this fixes the issue.
2026-02-11 15:53:30 +00:00
Noa d3f59480e2 Bump Rust to 1.93.0 (#4180)
# Description of Changes

Required in order to bump rolldown to its latest version, which I'm
planning to do afterwards. I also figure we may as well do this before
releasing a major version.

# Expected complexity level and risk

2

# Testing

n/a
2026-02-06 19:51:53 +00:00
Zeke Foppa 21cf6afe54 CI - Merge xtask-smoketest into cargo ci smoketests (#4185)
# Description of Changes

Just merging two CI packages into one.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

- [x] CI passes
- [x] `cargo ci smoketests prepare` still just builds the binaries

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@aol.com>
2026-02-06 00:17:06 +00:00
Tyler Cloutier 9686139dbc Translate smoketests from Python to Rust (#4102)
# Description of Changes

This PR translates all of our Python smoketests into Rust tests which
can be run from `cargo run`

## Motivation

The purpose of this fivefold:

1. All developers on the team are familiar with Rust
2. It simplifies our devops because we can drop Python as a dependency
to run the tests
3. You can now run all tests in the repo through the single `cargo test`
interface
4. Because we use the `SpacetimeDbGuard` and `cargo test`/`cargo
nextest` we can easily parallelize the smoke tests
5. The smoketests can now use machinery imported from SpacetimeDB crates
(e.g. `bsatn` etc.)

IMPORTANT NOTE!

There are several ways to implement the smoke tests in Rust (none are
great):

1. A separate xtask specifically for the smoke tests
- This doesn't solve the problem of the CLI tests which also use the
`guard` crate
    - Idiosyncratic way to run the smoke tests as opposed to cargo test
- Does NOT resolve the cargo within cargo problem because we still have
to build the test modules with cargo
2. A `build.rs` script in `guard` which first builds the executables as
a compile step for compiling guard
- Deadlocks on a cargo lock file conflict (Outer cargo compiles guard →
runs build.rs, inner cargo tries to acquire the build directory lock,
outer cargo holds the directory lock, deadlock)
- If you fix the deadlock by using different target dirs, it still looks
stuck on building guard because it's actually compiling all of
spacetimedb-standalone and spacetimedb-cli.
    - Still technically runs cargo inside of cargo.
3. Add `spacetimedb-cli` and `spacetimedb-standalone` as an artifact
dependency of the guard crate
- Has good and clear output but requires +nightly when running the
smoketests and CLI tests, otherwise won't do the right thing. See
https://github.com/rust-lang/cargo/issues/9096
4. Compile the executables at runtime during the tests themselves where
the first test takes a lock while the executables are building using
cargo within cargo
- Makes the tests look like they're taking a long time when they're just
waiting for the build to complete
- Requires relatively complex locking machinery across
binaries/tests/processes
5. A two step solution where the developer has to build the binaries
before calling the smoke tests
    - Very error prone

None of these are good. `xtask` is not bad, but doesn't enable us to run
other integration tests in other crates (e.g. the CLI)

(3) is the correct solution and has the best user experience, but it
requires nightly and I don't want to introduce that for all of our
tests.

I have chosen to do a combination of (1) and (4). You will now run the
smoketests with `cargo smoketest`. If you run `cargo test --all` (or use
`guard`) without doing `cargo smoketest` it will fall back to (4) which
compiles the executables at runtime. Running `cargo build` is the **only
way** to ensure that the executables are not stale because of the
internal fingerprint checking. Everything else is fragile not robust.

NOTE! There is no way to avoid cargo within cargo and have the smoke
tests be run as cargo tests because the modules under test must be
compiled with cargo.

# API and ABI breaking changes

Note that this is a BREAKING CHANGE to `cargo test --all`. The
smoketests are now part of `cargo test --all` unless you specifically
exclude them.

# Expected complexity level and risk

3, this is partially AI translated. We need to carefully review to
ensure the semantics have not regressed.

# 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. -->

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-02-04 21:44:32 +00:00
Mazdak Farrokhzad ae15508dee Identifiers: Refactor + Improve type-safety & performance (#4177)
# Description of Changes

The goal of this PR is to:
- Make it easy to switch our backing implementation of identifiers, as
seen in the commit changing to `LeanString`.
- Improve type safety of our identifiers by having every identifier
start with `RawIdentifier` and then `Identifier` is just a wrapper with
validation on construction. `TableName` and `ReducerName` are then just
wrappers around `Identifier`.
- Reduce allocation in `InstanceEnv` by using the now clone-on-write
O(1) + SSO optimized `Identifier`.
- Reduce allocations in the query engine as a consequence of improving
`RawIdentifier` and `Identifier`.
- Have `&'static str` strings be further optimized by avoiding to
allocate even for long ones. This is supported by `impl From<&'static
str> for RawIdentifier` as well as switching to `LeanString`.

The PR results in a roughly 2k TPS improvement over master for WASM +
hash indices. This should also help V8, as this is VM-agnostic.

# API and ABI breaking changes

None

# Expected complexity level and risk

3? Mostly just small changes in many places, but in a sea of small
changes, mistakes can happen.

# Testing

Covered by existing tests.
2026-02-04 20:54:56 +00:00
Phoebe Goldman 9167f4b19b Update librusty_v8.nix for our new V8 dependency version. (#4202)
# Description of Changes

And more precisely pin the Cargo dep, along with a comment.

# API and ABI breaking changes

N/a

# Expected complexity level and risk

1

# Testing

- [x] `nix build` now exits 0 and produces runnable binaries locally.
(`nix flake check` is still broken.)
2026-02-04 18:48:29 +00:00