Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
ebed4c3
Split WS into v1 and v2; make various changes in v2.
gefjon Jan 13, 2026
4fc9dc1
Merge remote-tracking branch 'origin/master' into phoebe/websocket-v2
gefjon Jan 14, 2026
7a1258a
Fix some copy-paste typos
gefjon Jan 14, 2026
05478c8
Nix `NoSuccessNotify`, add doc comments
gefjon Jan 15, 2026
4a4b10b
Update references to v1 WS format
gefjon Jan 15, 2026
dd020e6
Add doc comment to `TableUpdateRows`
gefjon Jan 21, 2026
e4e46c0
Fix compilation issue
jsdt Jan 29, 2026
f28f81e
Move compression into common and add new protocol option for v2
jsdt Jan 29, 2026
b621b2a
WIP on new subscription update format
jsdt Feb 4, 2026
8ca7795
WIP on subscription update stuff, and add UnsubscribeFlags
jsdt Feb 4, 2026
89a09c2
Move BsatnRowList to common and use it in v2
jsdt Feb 4, 2026
d9e9bfe
Update module subscription manager to group updates by client/query.
jsdt Feb 5, 2026
9437a55
Merge origin/master into jsdt/ws-v2
cloutiertyler Feb 5, 2026
0906a38
Derive Ord for TableName and ReducerName
cloutiertyler Feb 5, 2026
6a68b54
Fix Rust SDK import of RowListLen from common module
cloutiertyler Feb 6, 2026
aaa8b97
fix a issue from having missing files when merging
jsdt Feb 6, 2026
34328a8
Plumb reducer return value
jsdt Feb 6, 2026
a21b07d
finish send worker for v2
jsdt Feb 7, 2026
39dac16
send reducer result even if the client isn't getting something
jsdt Feb 7, 2026
bc1ebdd
More subscription manager
jsdt Feb 7, 2026
760379e
Cleanup
jsdt Feb 8, 2026
d9a8b0c
Merge branch 'master' into jsdt/ws-v2
jsdt Feb 8, 2026
b53b97c
Fix reducer return issue
jsdt Feb 8, 2026
b5b3757
tiny test
jsdt Feb 8, 2026
734f370
remove on errors
jsdt Feb 8, 2026
46d01fe
Add a simple test for removal
jsdt Feb 8, 2026
e27f45b
more add v2 sub
jsdt Feb 9, 2026
f4c73ca
One off queries and call procedure
jsdt Feb 9, 2026
7bdbb52
Add more one off query stuff
jsdt Feb 9, 2026
3571b98
fmt
jsdt Feb 9, 2026
516b0af
Send compression tags
jsdt Feb 9, 2026
3d3d3ef
Tweak v2 serialization
jsdt Feb 10, 2026
c14e5ed
Remove v2 subscriptions
jsdt Feb 10, 2026
25017c0
Don't filter empty ranges in `BsatnRowList`
gefjon Feb 10, 2026
db91218
send reducer errors
jsdt Feb 10, 2026
302de17
fix lint issues
jsdt Feb 11, 2026
4f2eb9d
Treat unhandled errors as fatal for v2 clients
jsdt Feb 11, 2026
9444733
Don't send any reducer info for v10 modules
jsdt Feb 11, 2026
ded3e23
Add back some metrics for v2
jsdt Feb 11, 2026
5c06e8a
Merge branch 'master' into jsdt/ws-v2
jsdt Feb 11, 2026
dd12852
Undo some unintentional changes
jsdt Feb 11, 2026
0eeb507
Merge branch 'master' into jsdt/ws-v2
jsdt Feb 12, 2026
1bdea5c
Remove reducer flags
jsdt Feb 12, 2026
3d6c6bf
Expand on a comment
jsdt Feb 12, 2026
ec84eb1
Revert "Remove reducer flags"
jsdt Feb 12, 2026
85681e5
clean up some match cases
jsdt Feb 12, 2026
ad9ca8b
move compression tags to common, fix metrics issue
jsdt Feb 12, 2026
67b8621
Comments and fix typo
jsdt Feb 12, 2026
228765a
Don't merge QueryRows
jsdt Feb 12, 2026
f342b51
Import compression from common
jsdt Feb 12, 2026
b83f26d
Bring some optimizations to v2 encoding
jsdt Feb 12, 2026
51363d5
Add/update some comments
jsdt Feb 12, 2026
5203cec
Fix lint
jsdt Feb 12, 2026
3ca35b3
Merge branch 'master' into jsdt/ws-v2
jsdt Feb 12, 2026
238b5c3
Refactor error sending into a helper
jsdt Feb 12, 2026
a616d60
Merge branch 'master' into jsdt/ws-v2
jsdt Feb 12, 2026
cde0b6b
Take view bindings from master
jsdt Feb 12, 2026
dabf177
Comment out the check diff for csharp
jsdt Feb 12, 2026
2d04f80
Change some warning to errors
jsdt Feb 12, 2026
6527dba
Merge branch 'master' into jsdt/ws-v2
jsdt Feb 12, 2026
149234a
Merge branch 'master' into jsdt/ws-v2
jsdt Feb 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -958,14 +958,15 @@ jobs:
exit 1
}

- name: Check client-api bindings are up to date
working-directory: sdks/csharp
run: |
bash tools~/gen-client-api.sh
"${GITHUB_WORKSPACE}"/tools/check-diff.sh src/SpacetimeDB/ClientApi || {
echo 'Error: Client API bindings are dirty. Please run `sdks/csharp/tools~/gen-client-api.sh`.'
exit 1
}
# TODO: Re-enable this once csharp is using the v2 ws api.
# - name: Check client-api bindings are up to date
# working-directory: sdks/csharp
# run: |
# bash tools~/gen-client-api.sh
# "${GITHUB_WORKSPACE}"/tools/check-diff.sh src/SpacetimeDB/ClientApi || {
# echo 'Error: Client API bindings are dirty. Please run `sdks/csharp/tools~/gen-client-api.sh`.'
# exit 1
# }

- name: Start SpacetimeDB
run: |
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ bench = false

[dependencies]
spacetimedb-client-api = { path = "../client-api" }
spacetimedb-client-api-messages = { path = "../client-api-messages" }
spacetimedb-core = { path = "../core", features = ["test"] }
spacetimedb-data-structures.workspace = true
spacetimedb-datastore.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions crates/bench/benches/subscription.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use spacetimedb::client::consume_each_list::ConsumeEachBuffer;
use spacetimedb::db::relational_db::RelationalDB;
use spacetimedb::error::DBError;
use spacetimedb::host::module_host::DatabaseTableUpdate;
use spacetimedb::identity::AuthCtx;
use spacetimedb::messages::websocket::BsatnFormat;
use spacetimedb::sql::ast::SchemaViewer;
use spacetimedb::subscription::query::compile_read_only_queryset;
use spacetimedb::subscription::row_list_builder_pool::BsatnRowListBuilderPool;
use spacetimedb::subscription::subscription::ExecutionSet;
use spacetimedb::subscription::tx::DeltaTx;
use spacetimedb::subscription::{collect_table_update, TableUpdateType};
use spacetimedb::{db::relational_db::RelationalDB, messages::websocket::Compression};
use spacetimedb_bench::database::BenchDatabase as _;
use spacetimedb_bench::spacetime_raw::SpacetimeRaw;
use spacetimedb_client_api_messages::websocket::v1::{BsatnFormat, Compression};
use spacetimedb_datastore::execution_context::Workload;
use spacetimedb_execution::pipelined::PipelinedProject;
use spacetimedb_primitives::{col_list, TableId};
Expand Down
35 changes: 19 additions & 16 deletions crates/cli/src/subcommands/subscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use futures::{Sink, SinkExt, TryStream, TryStreamExt};
use http::header;
use reqwest::Url;
use serde_json::Value;
use spacetimedb_client_api_messages::websocket::{self as ws, JsonFormat};
use spacetimedb_client_api_messages::websocket::v1 as ws_v1;
use spacetimedb_data_structures::map::HashMap;
use spacetimedb_lib::db::raw_def::v9::RawModuleDefV9;
use spacetimedb_lib::de::serde::{DeserializeWrapper, SeedWrapper};
Expand Down Expand Up @@ -71,16 +71,16 @@ pub fn cli() -> clap::Command {
.arg(common_args::server().help("The nickname, host name or URL of the server hosting the database"))
}

fn parse_msg_json(msg: &WsMessage) -> Option<ws::ServerMessage<JsonFormat>> {
fn parse_msg_json(msg: &WsMessage) -> Option<ws_v1::ServerMessage<ws_v1::JsonFormat>> {
let WsMessage::Text(msg) = msg else { return None };
serde_json::from_str::<DeserializeWrapper<ws::ServerMessage<JsonFormat>>>(msg)
serde_json::from_str::<DeserializeWrapper<ws_v1::ServerMessage<ws_v1::JsonFormat>>>(msg)
.inspect_err(|e| eprintln!("couldn't parse message from server: {e}"))
.map(|wrapper| wrapper.0)
.ok()
}

fn reformat_update<'a>(
msg: &'a ws::DatabaseUpdate<JsonFormat>,
msg: &'a ws_v1::DatabaseUpdate<ws_v1::JsonFormat>,
schema: &RawModuleDefV9,
) -> anyhow::Result<HashMap<&'a str, SubscriptionTable>> {
msg.tables
Expand Down Expand Up @@ -152,7 +152,7 @@ pub async fn exec(config: Config, args: &ArgMatches) -> Result<(), anyhow::Error
let mut req = url.into_client_request()?;
req.headers_mut().insert(
header::SEC_WEBSOCKET_PROTOCOL,
http::HeaderValue::from_static(ws::TEXT_PROTOCOL),
http::HeaderValue::from_static(ws_v1::TEXT_PROTOCOL),
);
// Add the authorization header, if any.
if let Some(auth_header) = api.con.auth_header.to_header() {
Expand Down Expand Up @@ -241,8 +241,8 @@ async fn subscribe<S>(ws: &mut S, query_strings: Box<[Box<str>]>) -> Result<(),
where
S: Sink<WsMessage, Error = WsError> + Unpin,
{
let msg = serde_json::to_string(&SerializeWrapper::new(ws::ClientMessage::<()>::Subscribe(
ws::Subscribe {
let msg = serde_json::to_string(&SerializeWrapper::new(ws_v1::ClientMessage::<()>::Subscribe(
ws_v1::Subscribe {
query_strings,
request_id: 0,
},
Expand All @@ -262,22 +262,22 @@ where
while let Some(msg) = ws.try_next().await.map_err(|source| Error::Websocket { source })? {
let Some(msg) = parse_msg_json(&msg) else { continue };
match msg {
ws::ServerMessage::InitialSubscription(sub) => {
ws_v1::ServerMessage::InitialSubscription(sub) => {
if let Some(module_def) = module_def {
let output = format_output_json(&sub.database_update, module_def)?;
tokio::io::stdout().write_all(output.as_bytes()).await?
}
break;
}
ws::ServerMessage::TransactionUpdate(ws::TransactionUpdate { status, .. }) => {
ws_v1::ServerMessage::TransactionUpdate(ws_v1::TransactionUpdate { status, .. }) => {
return Err(match status {
ws::UpdateStatus::Failed(msg) => Error::TransactionFailure { reason: msg },
ws_v1::UpdateStatus::Failed(msg) => Error::TransactionFailure { reason: msg },
_ => Error::Protocol {
details: RECV_TX_UPDATE,
},
})
}
ws::ServerMessage::TransactionUpdateLight(ws::TransactionUpdateLight { .. }) => {
ws_v1::ServerMessage::TransactionUpdateLight(ws_v1::TransactionUpdateLight { .. }) => {
return Err(Error::Protocol {
details: RECV_TX_UPDATE,
})
Expand Down Expand Up @@ -310,14 +310,14 @@ where

let Some(msg) = parse_msg_json(&msg) else { continue };
match msg {
ws::ServerMessage::InitialSubscription(_) => {
ws_v1::ServerMessage::InitialSubscription(_) => {
return Err(Error::Protocol {
details: "received a second initial subscription update",
})
}
ws::ServerMessage::TransactionUpdateLight(ws::TransactionUpdateLight { update, .. })
| ws::ServerMessage::TransactionUpdate(ws::TransactionUpdate {
status: ws::UpdateStatus::Committed(update),
ws_v1::ServerMessage::TransactionUpdateLight(ws_v1::TransactionUpdateLight { update, .. })
| ws_v1::ServerMessage::TransactionUpdate(ws_v1::TransactionUpdate {
status: ws_v1::UpdateStatus::Committed(update),
..
}) => {
let output = format_output_json(&update, module_def)?;
Expand All @@ -329,7 +329,10 @@ where
}
}

fn format_output_json(msg: &ws::DatabaseUpdate<JsonFormat>, schema: &RawModuleDefV9) -> Result<String, Error> {
fn format_output_json(
msg: &ws_v1::DatabaseUpdate<ws_v1::JsonFormat>,
schema: &RawModuleDefV9,
) -> Result<String, Error> {
let formatted = reformat_update(msg, schema).map_err(|source| Error::Reformat { source })?;
let output = serde_json::to_string(&formatted)? + "\n";

Expand Down
2 changes: 1 addition & 1 deletion crates/client-api-messages/examples/get_ws_schema.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use bytes::Bytes;
use spacetimedb_client_api_messages::websocket::{BsatnFormat, ClientMessage, ServerMessage};
use spacetimedb_client_api_messages::websocket::v1::{BsatnFormat, ClientMessage, ServerMessage};
use spacetimedb_lib::ser::serde::SerializeWrapper;
use spacetimedb_lib::{RawModuleDef, RawModuleDefV8};

Expand Down
Loading
Loading