Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9f9619a
A version that uses a ctor approach. It passes a test, haven't tried …
jsdt Apr 30, 2026
484bf37
actually add the test_utils
jsdt Apr 30, 2026
972d3e6
Flesh out the moduledef
jsdt Apr 30, 2026
e63a74a
Get a test datastore
jsdt May 1, 2026
78e6db8
Add more of reducercontext
jsdt May 1, 2026
1e30e04
Fix index methods
jsdt May 1, 2026
3961992
Add more procedure testing
jsdt May 5, 2026
c27a213
Before changing callback context
jsdt May 11, 2026
c0cdd34
Give callbacks the full TestContext
jsdt May 11, 2026
d9f4e9d
Add sleep callback
jsdt May 11, 2026
fec9a08
Implement for tests
jsdt May 11, 2026
e437e63
Typescript tests
jsdt May 14, 2026
aba828d
Get sql working for ts
jsdt May 14, 2026
ef63acb
Random fixes for ci test
jsdt May 14, 2026
a2a2161
Cleanup
jsdt May 15, 2026
4532fcc
Updates from proposal changes
jsdt Jun 12, 2026
a58ab30
Update http responder
jsdt Jun 17, 2026
2a0acbe
Merge remote-tracking branch 'origin/master' into jsdt/portable-datas…
jsdt Jul 6, 2026
8db3dd8
Fix post-merge test failures
jsdt Jul 6, 2026
032bea8
merge
jsdt Jul 10, 2026
9867744
Merge branch 'master' into jsdt/portable-datastore-2
jsdt Jul 13, 2026
e51eee0
Merge branch 'master' into jsdt/portable-datastore-2
jsdt Jul 13, 2026
d69ea44
Merge branch 'master' into jsdt/portable-datastore-2
jsdt Jul 16, 2026
e1dea85
Merge branch 'master' into jsdt/portable-datastore-2
jsdt Jul 17, 2026
015dc37
Fix some warnings
jsdt Jul 17, 2026
7749f2e
Merge branch 'master' into jsdt/portable-datastore-2
jsdt Jul 22, 2026
c3e8de0
Remove some extraneous changes
jsdt Jul 22, 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
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,34 @@ jobs:
- name: Run bindgen tests
run: cargo ci wasm-bindings

portable_datastore:
name: Check portable datastore
runs-on: spacetimedb-new-runner-2
env:
CARGO_TARGET_DIR: ${{ github.workspace }}/target
steps:
- uses: actions/checkout@v3

- uses: dsherret/rust-toolchain-file@v1
- name: Set default rust toolchain
run: rustup default $(rustup show active-toolchain | cut -d' ' -f1)
- run: echo ::add-matcher::.github/workflows/rust_matcher.json

- name: Install wasm target
run: rustup target add wasm32-unknown-unknown

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ github.workspace }}
shared-key: spacetimedb
# Let the smoketests job save the cache since it builds the most things
save-if: false
prefix-key: v1

- name: Run portable datastore checks
run: cargo ci portable-datastore

publish_checks:
needs: [merge_queue_noop]
if: ${{ needs.merge_queue_noop.outputs.skip != 'true' }}
Expand Down
45 changes: 45 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ members = [
"crates/paths",
"crates/pg",
"crates/physical-plan",
"crates/portable-datastore",
"crates/portable-datastore-wasm",
"crates/primitives",
"crates/query",
"crates/runtime",
Expand All @@ -39,6 +41,7 @@ members = [
"crates/standalone",
"crates/subscription",
"crates/table",
"crates/test-datastore",
"crates/testing",
"crates/update",
"modules/benchmarks",
Expand Down Expand Up @@ -159,6 +162,7 @@ spacetimedb-standalone = { path = "crates/standalone", version = "=2.7.0" }
spacetimedb-subscription = { path = "crates/subscription", version = "=2.7.0" }
spacetimedb-sql-parser = { path = "crates/sql-parser", version = "=2.7.0" }
spacetimedb-table = { path = "crates/table", version = "=2.7.0" }
spacetimedb-test-datastore = { path = "crates/test-datastore", version = "=2.7.0" }

# Prevent `ahash` from pulling in `getrandom` by disabling default features.
# Modules use `getrandom02` and we need to prevent an incompatible version
Expand Down
3 changes: 3 additions & 0 deletions crates/bindings-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ license-file = "LICENSE"
description = "Easy support for interacting between SpacetimeDB and Rust."
rust-version.workspace = true

[features]
test-utils = []

[lib]
proc-macro = true
# Benching off, because of https://bheisler.github.io/criterion.rs/book/faq.html#cargo-bench-gives-unrecognized-option-errors-for-valid-command-line-options
Expand Down
10 changes: 9 additions & 1 deletion crates/bindings-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ use quote::quote;
use std::time::Duration;
use syn::{parse::ParseStream, Attribute};
use syn::{ItemConst, ItemFn};
use util::{cvt_attr, ok_or_compile_error};
use util::{cvt_attr, native_test_utils_registration, ok_or_compile_error};

mod sym {
/// A symbol known at compile-time against
Expand Down Expand Up @@ -305,6 +305,9 @@ pub fn client_visibility_filter(args: StdTokenStream, item: StdTokenStream) -> S
let item: ItemConst = syn::parse(item)?;
let rls_ident = item.ident.clone();
let register_rls_symbol = format!("__preinit__20_register_row_level_security_{rls_ident}");
let test_utils_registration = native_test_utils_registration(quote! {
spacetimedb::rt::register_row_level_security(#rls_ident.sql_text())
});

Ok(quote! {
#item
Expand All @@ -314,6 +317,8 @@ pub fn client_visibility_filter(args: StdTokenStream, item: StdTokenStream) -> S
extern "C" fn __register_client_visibility_filter() {
spacetimedb::rt::register_row_level_security(#rls_ident.sql_text())
}

#test_utils_registration
};
})
})
Expand Down Expand Up @@ -357,6 +362,7 @@ pub fn settings(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
},
_ => unreachable!("validated above"),
};
let test_utils_registration = native_test_utils_registration(register_call.clone());

Ok(quote! {
#item
Expand All @@ -366,6 +372,8 @@ pub fn settings(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
extern "C" fn __register_setting() {
#register_call
}

#test_utils_registration
};
})
})
Expand Down
6 changes: 5 additions & 1 deletion crates/bindings-macro/src/procedure.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::reducer::{assert_only_lifetime_generics, extract_typed_args, generate_explicit_names_impl};
use crate::sym;
use crate::util::{check_duplicate, ident_to_litstr, match_meta};
use crate::util::{check_duplicate, ident_to_litstr, match_meta, native_test_utils_registration};
use proc_macro2::TokenStream;
use quote::quote;
use syn::parse::Parser as _;
Expand Down Expand Up @@ -86,12 +86,16 @@ pub(crate) fn procedure_impl(_args: ProcedureArgs, original_function: &ItemFn) -
spacetimedb::rt::register_procedure::<_, _, #func_name>(#func_name)
}
};
let test_utils_registration = native_test_utils_registration(quote! {
__register_describer()
});

let generate_explicit_names = generate_explicit_names_impl(&procedure_name.value(), func_name, explicit_name);

Ok(quote! {
const _: () = {
#generated_describe_function
#test_utils_registration
};
#[allow(non_camel_case_types)]
#vis struct #func_name { _never: ::core::convert::Infallible }
Expand Down
6 changes: 5 additions & 1 deletion crates/bindings-macro/src/reducer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::sym;
use crate::util::{check_duplicate, check_duplicate_msg, ident_to_litstr, match_meta};
use crate::util::{check_duplicate, check_duplicate_msg, ident_to_litstr, match_meta, native_test_utils_registration};
use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned};
use syn::parse::Parser as _;
Expand Down Expand Up @@ -140,10 +140,14 @@ pub(crate) fn reducer_impl(args: ReducerArgs, original_function: &ItemFn) -> syn
spacetimedb::rt::register_reducer::<_, #func_name>(#func_name)
}
};
let test_utils_registration = native_test_utils_registration(quote! {
__register_describer()
});

Ok(quote! {
const _: () = {
#generated_describe_function
#test_utils_registration
};
#[allow(non_camel_case_types)]
#vis struct #func_name { _never: ::core::convert::Infallible }
Expand Down
53 changes: 41 additions & 12 deletions crates/bindings-macro/src/table.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::sats;
use crate::sym;
use crate::util::{check_duplicate, check_duplicate_msg, match_meta};
use crate::util::{check_duplicate, check_duplicate_msg, match_meta, native_test_utils_registration};
use core::slice;
use heck::ToSnakeCase;
use proc_macro2::{Span, TokenStream};
Expand Down Expand Up @@ -589,7 +589,7 @@ impl ValidatedIndex<'_> {
quote! {
#[doc = #doc]
#vis fn #column_ident(&self) -> #unique_ty<#tbl_token, #col_ty, __indices::#index_ident> {
#unique_ty::__NEW
#unique_ty::__new(self.__backend.clone())
}
}
}
Expand Down Expand Up @@ -630,7 +630,7 @@ impl ValidatedIndex<'_> {
quote! {
#[doc = #doc]
#vis fn #index_ident(&self) -> #handle_ty<#tbl_token, (#(#col_tys,)*), __indices::#index_ident> {
#handle_ty::__NEW
#handle_ty::__new(self.__backend.clone())
}
}
}
Expand Down Expand Up @@ -677,6 +677,7 @@ impl ValidatedIndex<'_> {
#vis struct #index_ident;
impl spacetimedb::table::#index_kind_trait for #index_ident {}
impl spacetimedb::table::Index for #index_ident {
const INDEX_NAME: &'static str = #index_name;
const NUM_COLS_INDEXED: usize = #num_cols;
fn index_id() -> spacetimedb::table::IndexId {
static INDEX_ID: std::sync::OnceLock<spacetimedb::table::IndexId> = std::sync::OnceLock::new();
Expand Down Expand Up @@ -1136,6 +1137,9 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
#(const SCHEDULE: Option<spacetimedb::table::ScheduleDesc<'static>> = Some(#schedule);)*

#table_id_from_name_func
fn __backend(&self) -> &spacetimedb::table::TableHandleBackend {
&self.__backend
}
#default_fn
}
};
Expand All @@ -1157,12 +1161,14 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
#[allow(non_camel_case_types, dead_code)]
#vis trait #table_ident {
#[allow(non_camel_case_types, dead_code)]
fn #table_ident(&self) -> &#tablehandle_ident;
fn #table_ident(&self) -> #tablehandle_ident;
}
impl #table_ident for spacetimedb::Local {
#[allow(non_camel_case_types, dead_code)]
fn #table_ident(&self) -> &#tablehandle_ident {
&#tablehandle_ident {}
fn #table_ident(&self) -> #tablehandle_ident {
#tablehandle_ident {
__backend: self.__table_backend(),
}
}
}
};
Expand All @@ -1171,12 +1177,14 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
#[allow(non_camel_case_types, dead_code)]
#vis trait #view_trait_ident {
#[allow(non_camel_case_types, dead_code)]
fn #table_ident(&self) -> &#viewhandle_ident;
fn #table_ident(&self) -> #viewhandle_ident;
}
impl #view_trait_ident for spacetimedb::LocalReadOnly {
#[inline]
fn #table_ident(&self) -> &#viewhandle_ident {
&#viewhandle_ident {}
fn #table_ident(&self) -> #viewhandle_ident {
#viewhandle_ident {
__backend: self.__table_backend(),
}
}
}
};
Expand Down Expand Up @@ -1263,13 +1271,19 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
let tablehandle_def = quote! {
#[allow(non_camel_case_types)]
#[non_exhaustive]
#vis struct #tablehandle_ident {}
#vis struct #tablehandle_ident {
#[doc(hidden)]
pub __backend: spacetimedb::table::TableHandleBackend,
}
};

let viewhandle_def = quote! {
#[allow(non_camel_case_types)]
#[non_exhaustive]
#vis struct #viewhandle_ident {}
#vis struct #viewhandle_ident {
#[doc(hidden)]
pub __backend: spacetimedb::table::TableHandleBackend,
}
};

let struct_name = original_struct_ident.to_string();
Expand All @@ -1281,6 +1295,13 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
quote! {}
};

let test_utils_registration = native_test_utils_registration(quote! {
spacetimedb::rt::register_table::<#tablehandle_ident>();
spacetimedb::test_utils::__register_table_name(
<#tablehandle_ident as spacetimedb::table::TableInternal>::TABLE_NAME,
);
});

let emission = quote! {
const _: () = {
#(let _ = <#field_types as spacetimedb::rt::TableColumn>::_ITEM;)*
Expand All @@ -1304,7 +1325,13 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
impl #viewhandle_ident {
#[inline]
pub fn count(&self) -> u64 {
spacetimedb::table::count::<#tablehandle_ident>()
let table_id = self
.__backend
.table_id(<#tablehandle_ident as spacetimedb::table::TableInternal>::TABLE_NAME)
.expect("table_id_from_name() call failed");
self.__backend
.table_row_count(table_id)
.expect("datastore_table_row_count() call failed")
}

#(#index_accessors_ro)*
Expand All @@ -1322,6 +1349,8 @@ pub(crate) fn table_impl(mut args: TableArgs, item: &syn::DeriveInput) -> syn::R
}

#describe_table_func

#test_utils_registration
};
};

Expand Down
Loading
Loading