Skip to content

Commit 624d9fc

Browse files
committed
Merge remote-tracking branch 'origin/master' into kim/reset-database
2 parents f1b3b33 + a952ba5 commit 624d9fc

File tree

165 files changed

+38726
-6815
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

165 files changed

+38726
-6815
lines changed

.github/workflows/docs-check-links.yml

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Docs / Publish
2+
3+
permissions:
4+
contents: read
5+
6+
on:
7+
push:
8+
branches:
9+
- docs/release
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v3
17+
18+
- name: Set up Node.js
19+
uses: actions/setup-node@v3
20+
with:
21+
node-version: '22'
22+
23+
- uses: pnpm/action-setup@v4
24+
with:
25+
run_install: true
26+
27+
- name: Get pnpm store directory
28+
working-directory: sdks/typescript
29+
shell: bash
30+
run: |
31+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
32+
33+
- uses: actions/cache@v4
34+
name: Setup pnpm cache
35+
with:
36+
path: ${{ env.STORE_PATH }}
37+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
38+
restore-keys: |
39+
${{ runner.os }}-pnpm-store-
40+
41+
- name: Install dependencies
42+
working-directory: docs
43+
run: pnpm install
44+
45+
- name: Docusaurus build
46+
working-directory: docs
47+
run: pnpm build
48+
49+
- name: Publish docs to S3
50+
uses: shallwefootball/s3-upload-action@master
51+
with:
52+
aws_key_id: ${{ secrets.DOCS_AWS_KEY_ID }}
53+
aws_secret_access_key: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY}}
54+
aws_bucket: spacetimedb-docs
55+
source_dir: docs/build
56+
destination_dir: 'docs'

.github/workflows/docs-test.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Docs / Test
2+
permissions:
3+
contents: read
4+
5+
on:
6+
pull_request:
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout repository
13+
uses: actions/checkout@v3
14+
15+
- name: Set up Node.js
16+
uses: actions/setup-node@v3
17+
with:
18+
node-version: '22'
19+
20+
- uses: pnpm/action-setup@v4
21+
with:
22+
run_install: true
23+
24+
- name: Get pnpm store directory
25+
working-directory: sdks/typescript
26+
shell: bash
27+
run: |
28+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
29+
30+
- uses: actions/cache@v4
31+
name: Setup pnpm cache
32+
with:
33+
path: ${{ env.STORE_PATH }}
34+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
35+
restore-keys: |
36+
${{ runner.os }}-pnpm-store-
37+
38+
- name: Install dependencies
39+
working-directory: docs
40+
run: pnpm install
41+
42+
- name: Docusaurus build
43+
working-directory: docs
44+
run: pnpm build

.github/workflows/docs-validate-nav-build.yml

Lines changed: 0 additions & 79 deletions
This file was deleted.

crates/bindings-macro/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//
99
// (private documentation for the macro authors is totally fine here and you SHOULD write that!)
1010

11+
mod procedure;
1112
mod reducer;
1213
mod sats;
1314
mod table;
@@ -105,6 +106,14 @@ mod sym {
105106
}
106107
}
107108

109+
#[proc_macro_attribute]
110+
pub fn procedure(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
111+
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
112+
let args = procedure::ProcedureArgs::parse(args)?;
113+
procedure::procedure_impl(args, original_function)
114+
})
115+
}
116+
108117
#[proc_macro_attribute]
109118
pub fn reducer(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
110119
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
@@ -116,7 +125,7 @@ pub fn reducer(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
116125
#[proc_macro_attribute]
117126
pub fn view(args: StdTokenStream, item: StdTokenStream) -> StdTokenStream {
118127
cvt_attr::<ItemFn>(args, item, quote!(), |args, original_function| {
119-
let args = view::ViewArgs::parse(args)?;
128+
let args = view::ViewArgs::parse(args, &original_function.sig.ident)?;
120129
view::view_impl(args, original_function)
121130
})
122131
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
use crate::reducer::{assert_only_lifetime_generics, extract_typed_args};
2+
use crate::sym;
3+
use crate::util::{check_duplicate, ident_to_litstr, match_meta};
4+
use proc_macro2::TokenStream;
5+
use quote::quote;
6+
use syn::parse::Parser as _;
7+
use syn::{ItemFn, LitStr};
8+
9+
#[derive(Default)]
10+
pub(crate) struct ProcedureArgs {
11+
/// For consistency with reducers: allow specifying a different export name than the Rust function name.
12+
name: Option<LitStr>,
13+
}
14+
15+
impl ProcedureArgs {
16+
pub(crate) fn parse(input: TokenStream) -> syn::Result<Self> {
17+
let mut args = Self::default();
18+
syn::meta::parser(|meta| {
19+
match_meta!(match meta {
20+
sym::name => {
21+
check_duplicate(&args.name, &meta)?;
22+
args.name = Some(meta.value()?.parse()?);
23+
}
24+
});
25+
Ok(())
26+
})
27+
.parse2(input)?;
28+
Ok(args)
29+
}
30+
}
31+
32+
pub(crate) fn procedure_impl(args: ProcedureArgs, original_function: &ItemFn) -> syn::Result<TokenStream> {
33+
let func_name = &original_function.sig.ident;
34+
let vis = &original_function.vis;
35+
36+
let procedure_name = args.name.unwrap_or_else(|| ident_to_litstr(func_name));
37+
38+
assert_only_lifetime_generics(original_function, "procedures")?;
39+
40+
let typed_args = extract_typed_args(original_function)?;
41+
42+
// TODO: Require that procedures be `async` functions syntactically,
43+
// and use `futures_util::FutureExt::now_or_never` to poll them.
44+
// if !&original_function.sig.asyncness.is_some() {
45+
// return Err(syn::Error::new_spanned(
46+
// original_function.sig.clone(),
47+
// "procedures must be `async`",
48+
// ));
49+
// };
50+
51+
// Extract all function parameter names.
52+
let opt_arg_names = typed_args.iter().map(|arg| {
53+
if let syn::Pat::Ident(i) = &*arg.pat {
54+
let name = i.ident.to_string();
55+
quote!(Some(#name))
56+
} else {
57+
quote!(None)
58+
}
59+
});
60+
61+
let arg_tys = typed_args.iter().map(|arg| arg.ty.as_ref()).collect::<Vec<_>>();
62+
let first_arg_ty = arg_tys.first().into_iter();
63+
let rest_arg_tys = arg_tys.iter().skip(1);
64+
65+
// Extract the return type.
66+
let ret_ty_for_assert = match &original_function.sig.output {
67+
syn::ReturnType::Default => None,
68+
syn::ReturnType::Type(_, t) => Some(&**t),
69+
}
70+
.into_iter();
71+
72+
let ret_ty_for_info = match &original_function.sig.output {
73+
syn::ReturnType::Default => quote!(()),
74+
syn::ReturnType::Type(_, t) => quote!(#t),
75+
};
76+
77+
let register_describer_symbol = format!("__preinit__20_register_describer_{}", procedure_name.value());
78+
79+
let lifetime_params = &original_function.sig.generics;
80+
let lifetime_where_clause = &lifetime_params.where_clause;
81+
82+
let generated_describe_function = quote! {
83+
#[export_name = #register_describer_symbol]
84+
pub extern "C" fn __register_describer() {
85+
spacetimedb::rt::register_procedure::<_, _, #func_name>(#func_name)
86+
}
87+
};
88+
89+
Ok(quote! {
90+
const _: () = {
91+
#generated_describe_function
92+
};
93+
#[allow(non_camel_case_types)]
94+
#vis struct #func_name { _never: ::core::convert::Infallible }
95+
const _: () = {
96+
fn _assert_args #lifetime_params () #lifetime_where_clause {
97+
#(let _ = <#first_arg_ty as spacetimedb::rt::ProcedureContextArg>::_ITEM;)*
98+
#(let _ = <#rest_arg_tys as spacetimedb::rt::ProcedureArg>::_ITEM;)*
99+
#(let _ = <#ret_ty_for_assert as spacetimedb::rt::IntoProcedureResult>::to_result;)*
100+
}
101+
};
102+
impl #func_name {
103+
fn invoke(__ctx: spacetimedb::ProcedureContext, __args: &[u8]) -> spacetimedb::ProcedureResult {
104+
spacetimedb::rt::invoke_procedure(#func_name, __ctx, __args)
105+
}
106+
}
107+
#[automatically_derived]
108+
impl spacetimedb::rt::FnInfo for #func_name {
109+
/// The type of this function.
110+
type Invoke = spacetimedb::rt::ProcedureFn;
111+
112+
/// The function kind, which will cause scheduled tables to accept procedures.
113+
type FnKind = spacetimedb::rt::FnKindProcedure<#ret_ty_for_info>;
114+
115+
/// The name of this function
116+
const NAME: &'static str = #procedure_name;
117+
118+
/// The parameter names of this function
119+
const ARG_NAMES: &'static [Option<&'static str>] = &[#(#opt_arg_names),*];
120+
121+
/// The pointer for invoking this function
122+
const INVOKE: spacetimedb::rt::ProcedureFn = #func_name::invoke;
123+
124+
/// The return type of this function
125+
fn return_type(ts: &mut impl spacetimedb::sats::typespace::TypespaceBuilder) -> Option<spacetimedb::sats::AlgebraicType> {
126+
Some(<#ret_ty_for_info as spacetimedb::SpacetimeType>::make_type(ts))
127+
}
128+
}
129+
})
130+
}

0 commit comments

Comments
 (0)