listActions and editActions works

This commit is contained in:
Sebastian Moser
2026-04-02 17:18:23 +02:00
parent 94f0a960f6
commit 562b1abe9c
39 changed files with 2488 additions and 793 deletions

View File

@@ -42,6 +42,13 @@ impl C2vi {
}
pub fn c2vi(mize: &mut Mize) -> MizeResult<()> {
#[cfg(feature = "client")]
c2vi_client(mize)?;
Ok(())
}
pub fn c2vi_client(mize: &mut Mize) -> MizeResult<()> {
//let storage_path = mize.get_config("c2vi.local_storage_path")?.as_
let storage_path = "/home/me/work/app-data/ppc";
println!("storage_path: {}", storage_path);

View File

@@ -312,7 +312,7 @@ impl Mize {
part: Some(part.take().unwrap()),
mize: self.clone(),
}),
None => Err(mize_err!("Part not found or currently taken")),
None => Err(mize_err!("Part '{name}' not found or currently taken")),
}
}
pub fn has_part(&mut self, name: &str) -> bool {
@@ -909,6 +909,7 @@ impl Mize {
let part_names = self.part_names();
for part_name in part_names {
let mut part = self.get_part(part_name)?;
//println!("running part {part_name}");
part.run(&mut self.clone())?;
}
let mut threads_inner = self.threads.lock().unwrap();
@@ -924,11 +925,8 @@ impl Mize {
&mut self,
name: &str,
) -> MizeResult<MizePartGuard<T>> {
println!("Getting part native hiiiiiii");
let mut dyn_guard = self.get_part(name)?;
println!("Getting part native hiiiiiii two");
let part = dyn_guard.part.take().unwrap();
println!("Getting part native hiiiiiii three");
drop(dyn_guard);
let concrete_part = part.into_any().downcast::<T>().unwrap();
Ok(MizePartGuard {

View File

@@ -205,6 +205,13 @@ impl ItemData {
return Ok(value.into_item_data());
}
pub fn to_toml(&self) -> MizeResult<String> {
let mut out_string = String::new();
let toml_serializer = toml::Serializer::new(&mut out_string);
CborValue::serialize(&self.cbor(), toml_serializer)?;
Ok(out_string)
}
pub fn value_string(self) -> MizeResult<String> {
match self.cbor() {
CborValue::Text(string) => Ok(string.to_owned()),
@@ -212,6 +219,13 @@ impl ItemData {
}
}
pub fn value_bool(self) -> MizeResult<bool> {
match self.cbor() {
CborValue::Bool(val) => Ok(*val),
_ => Err(mize_err!("this ItemData has no string value")),
}
}
pub fn from_string<S: Into<String>>(into_string: S) -> ItemData {
let string = into_string.into();
let data = CborValue::Text(string);

View File

@@ -33,6 +33,9 @@ webbrowser = { version = "1.2.0", optional = true }
base64 = { version = "0.22.1", optional = true }
dioxus-web = { version = "0.7.3", optional = true }
web-sys = { version = "0.3.91", optional = true }
spacetimedb-sdk = "2.1.0"
flume = "0.12.0"
chrono = "0.4.44"
[[bin]]
name = "ppc"
@@ -44,11 +47,13 @@ path = "lib.rs"
name = "ppc"
[features]
default = ["target-os", "desktop", "server"]
default = ["target-os", "server", "client"]
target-os = [ "clap", "mize/target-os", "marts/target-os", "tracing", "webbrowser", "base64", "serde_json", "serde" ]
target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-js", "marts/target-js", "base64", "serde_json", "serde", "openidconnect", "dioxus", "dioxus-web", "web-sys", "web-sys/Document", "dioxus/web" ]
server = [ "axum", "axum-extra", "openidconnect", "serde", "serde_json", "reqwest", "rand", "url", "time", "tokio", "dioxus/ssr", "dioxus/server", "dioxus/fullstack", "dioxus/router", "dioxus-ssr", "html-escape", "axum-oidc", "tower", "tower-sessions", "marts/server", "target-os" ]
desktop = ["dioxus/desktop", "marts/desktop", "target-os"]
client = []
webbrowser = ["dep:webbrowser"]
[package.metadata.wasm-pack.profile.release]

View File

@@ -3,10 +3,11 @@ use base64::{
alphabet::STANDARD,
engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig},
};
use mize::{Mize, MizeError, MizePart, MizeResult, mize_err, mize_part};
use mize::{Mize, MizeError, MizePart, MizeResult, item::ItemData, mize_err, mize_part};
use openidconnect::{
AuthorizationCode, ClientId, CsrfToken, IssuerUrl, Nonce, OAuth2TokenResponse,
PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, RefreshToken, Scope,
AuthorizationCode, ClientId, CsrfToken, DeviceAuthorizationResponse,
EmptyExtraDeviceAuthorizationFields, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge,
PkceCodeVerifier, RedirectUrl, RefreshToken, Scope,
core::{CoreAuthenticationFlow, CoreClient, CoreProviderMetadata},
};
use serde::{Deserialize, Serialize};
@@ -93,10 +94,8 @@ pub fn client_auth(mize: &mut Mize) -> MizeResult<()> {
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
cli.subcommand(Command::new("login"), |_, mut mize| {
let secrets = mize.spawn_async_blocking("client_auth", auth_flow(mize_clone))?;
println!("hereeeeee oneeeeeeeeee");
let mut auth = mize.get_part_native::<ClientAuth>("client_auth")?;
println!("hereeeeee two");
write_secrets(&mut mize, &secrets)?;
let mut auth = mize.get_part_native::<ClientAuth>("client_auth")?;
auth.secrets = Some(secrets);
Ok(())
});
@@ -127,6 +126,14 @@ fn write_secrets(mize: &mut Mize, secrets: &ClientSecrets) -> MizeResult<()> {
let secrets_string = serde_json::to_string(secrets)?;
std::fs::write(secrets_file_path, secrets_string)?;
// update the spacetimedb_token in XDG_CONFIG_HOME/spacetime/cli.toml config file if configured to do so
if mize
.get_config("auth.client.update_spacetime_token")?
.value_bool()?
{
update_spacetimedb_token(&secrets.id_token.as_str())?;
}
Ok(())
}
@@ -136,121 +143,150 @@ struct Combined<'a> {
state: &'a str,
}
use openidconnect::reqwest::Client as HttpClient;
use openidconnect::{AuthUrl, DeviceAuthorizationUrl};
use std::time::Duration;
use tokio::time::sleep;
async fn auth_flow(mut mize: Mize) -> MizeResult<ClientSecrets> {
// ===== CONFIG =====
// Replace these with your issuer, client id and the public redirect URL served by the axum app.
let issuer = mize.get_config("auth.client.issuer")?.value_string()?;
let client_id = mize.get_config("auth.client.client_id")?.value_string()?;
let redirect_url = mize
.get_config("auth.client.redirect_url")?
.value_string()?;
let issuer = IssuerUrl::new(issuer)?;
let client_id = ClientId::new(client_id);
let redirect_uri = RedirectUrl::new(redirect_url)?;
let http_client = HttpClient::new();
// Teach openidconnect-rs about the device authorization url.
#[derive(Clone, Debug, Deserialize, Serialize)]
struct MyExtraProviderMetadata {
device_authorization_endpoint: String,
}
use openidconnect::AdditionalProviderMetadata;
use openidconnect::ProviderMetadata;
use openidconnect::core::{
CoreAuthDisplay, CoreClaimName, CoreClaimType, CoreClient, CoreClientAuthMethod,
CoreDeviceAuthorizationResponse, CoreGrantType, CoreJsonWebKey, CoreJsonWebKeyType,
CoreJsonWebKeyUse, CoreJweContentEncryptionAlgorithm, CoreJweKeyManagementAlgorithm,
CoreJwsSigningAlgorithm, CoreResponseMode, CoreResponseType, CoreSubjectIdentifierType,
};
impl AdditionalProviderMetadata for MyExtraProviderMetadata {}
type MyProviderMetadata = ProviderMetadata<
MyExtraProviderMetadata,
CoreAuthDisplay,
CoreClientAuthMethod,
CoreClaimName,
CoreClaimType,
CoreGrantType,
CoreJweContentEncryptionAlgorithm,
CoreJweKeyManagementAlgorithm,
CoreJsonWebKey,
CoreResponseMode,
CoreResponseType,
CoreSubjectIdentifierType,
>;
// Discover provider metadata
let provider_metadata =
CoreProviderMetadata::discover_async(issuer, &openidconnect::reqwest::Client::new())
.await?;
let provider_metadata: MyProviderMetadata =
MyProviderMetadata::discover_async(issuer, &http_client).await?;
let device_auth_url = provider_metadata
.additional_metadata()
.device_authorization_endpoint
.clone();
let client = CoreClient::from_provider_metadata(
provider_metadata,
client_id,
None, // no client secret for public clients
None, // public client
)
.set_redirect_uri(redirect_uri);
.set_device_authorization_url(DeviceAuthorizationUrl::new(device_auth_url)?);
// ===== PKCE + state + nonce =====
let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256();
let csrf_token = CsrfToken::new_random();
let csrf_token_clone = csrf_token.clone();
let nonce = Nonce::new_random();
// ===== DEVICE AUTH REQUEST =====
let details: Result<DeviceAuthorizationResponse<EmptyExtraDeviceAuthorizationFields>, _> =
client
.exchange_device_code()
.add_scope(Scope::new("openid".into()))
.add_scope(Scope::new("profile".into()))
.add_scope(Scope::new("offline_access".into()))
.request_async(&http_client)
.await;
// Build the authorization URL - include code_challenge and state
let (auth_url, _csrf_token_returned, _nonce_returned) = client
.authorize_url(
CoreAuthenticationFlow::AuthorizationCode,
move || csrf_token_clone.clone(),
move || nonce.clone(),
)
.set_pkce_challenge(pkce_challenge)
.add_scope(Scope::new("openid".to_string()))
.add_scope(Scope::new("profile".to_string()))
.url();
let details = match details {
Ok(val) => val,
Err(err) => {
println!("err: {:?}", err);
println!("err: {}", err);
panic!();
}
};
println!("Opening browser to authenticate...");
println!(
"If your browser does not open automatically, visit:\n\n{}\n",
auth_url
"If your browser does not open automatically, open this URL in it:\n{}\n",
details.verification_uri_complete().unwrap().secret()
);
println!(
"Or enter this PPC login code:\n{}\n",
details.user_code().secret()
);
#[cfg(feature = "target-os")]
{
// Try to open browser (best-effort)
if let Err(e) = webbrowser::open(auth_url.as_str()) {
eprintln!("Failed to open browser automatically: {}", e);
if let Some(uri_complete) = details.verification_uri_complete() {
let _ = webbrowser::open(details.verification_uri_complete().unwrap().secret());
}
}
#[cfg(feature = "target-obsidian")]
{
console_log!("try to open auth url in browser");
}
println!("When the authorization completes, the web page will show the code (and state).");
print!("Paste login string here: ");
io::stdout().flush()?;
// Read user input
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let input = input.trim();
if input.is_empty() {
return Err(mize_err!("No login string provided"));
}
let base64_engine = GeneralPurpose::new(
&STANDARD,
GeneralPurposeConfig::new().with_decode_padding_mode(DecodePaddingMode::RequireNone),
);
let json_bytes = base64_engine.decode(input)?;
let json_str = String::from_utf8(json_bytes)?;
let combined: Combined = serde_json::from_str(json_str.as_str())?;
if combined.state != csrf_token.secret() {
return Err(mize_err!(
"State mismatch: pasted state does not match expected value"
));
} else {
println!("State is valid");
};
// Perform token exchange
let token_response = client
.exchange_code(AuthorizationCode::new(combined.code.to_string()))?
.set_pkce_verifier(PkceCodeVerifier::new(pkce_verifier.secret().to_string()))
.request_async(&openidconnect::reqwest::Client::new())
.exchange_device_access_token(&details)?
.request_async(
&http_client,
async |dur: Duration| {
tokio::time::sleep(dur);
},
None,
)
.await?;
// ===== TOKENS =====
let id_token = token_response
.extra_fields()
.id_token()
.ok_or(mize_err!("no id_token"))?;
//let refresh = token_response.refresh_token();
println!("\n=== Token response ===");
println!("Access token: {:?}", token_response.access_token().secret());
println!("ID token: {}", id_token.to_string());
//println!("Refresh token: {}", refresh.secret());
let refresh = token_response
.refresh_token()
.ok_or(mize_err!("no refresh token present"))?;
Ok(ClientSecrets {
id_token: id_token.to_string(),
access_token: token_response.access_token().secret().to_string(),
refresh_token: "".to_string(),
refresh_token: refresh.secret().to_owned(),
})
}
fn update_spacetimedb_token(new_token: &str) -> MizeResult<()> {
// Resolve config directory
let config_dir = match std::env::var("XDG_CONFIG_HOME") {
Ok(val) => PathBuf::from(val),
Err(_) => {
let home = std::env::var("HOME")?;
std::path::PathBuf::from(home).join(".config")
}
};
let file_path = config_dir.join("spacetime").join("cli.toml");
// Read existing file (or create empty document if it doesn't exist)
let content = std::fs::read_to_string(&file_path).unwrap_or_default();
let mut data = ItemData::from_toml(content.as_str())?;
// Update the field
data.set_path("spacetimedb_token", new_token)?;
// Write back
std::fs::write(&file_path, data.to_toml()?)?;
Ok(())
}

View File

@@ -0,0 +1,159 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::activity_type::Activity;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `activities`.
///
/// Obtain a handle from the [`ActivitiesTableAccess::activities`] method on [`super::RemoteTables`],
/// like `ctx.db.activities()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.activities().on_insert(...)`.
pub struct ActivitiesTableHandle<'ctx> {
imp: __sdk::TableHandle<Activity>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `activities`.
///
/// Implemented for [`super::RemoteTables`].
pub trait ActivitiesTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`ActivitiesTableHandle`], which mediates access to the table `activities`.
fn activities(&self) -> ActivitiesTableHandle<'_>;
}
impl ActivitiesTableAccess for super::RemoteTables {
fn activities(&self) -> ActivitiesTableHandle<'_> {
ActivitiesTableHandle {
imp: self.imp.get_table::<Activity>("activities"),
ctx: std::marker::PhantomData,
}
}
}
pub struct ActivitiesInsertCallbackId(__sdk::CallbackId);
pub struct ActivitiesDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for ActivitiesTableHandle<'ctx> {
type Row = Activity;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = Activity> + '_ {
self.imp.iter()
}
type InsertCallbackId = ActivitiesInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> ActivitiesInsertCallbackId {
ActivitiesInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: ActivitiesInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = ActivitiesDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> ActivitiesDeleteCallbackId {
ActivitiesDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: ActivitiesDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct ActivitiesUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for ActivitiesTableHandle<'ctx> {
type UpdateCallbackId = ActivitiesUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> ActivitiesUpdateCallbackId {
ActivitiesUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: ActivitiesUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `id` unique index on the table `activities`,
/// which allows point queries on the field of the same name
/// via the [`ActivitiesIdUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.activities().id().find(...)`.
pub struct ActivitiesIdUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<Activity, u64>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> ActivitiesTableHandle<'ctx> {
/// Get a handle on the `id` unique index on the table `activities`.
pub fn id(&self) -> ActivitiesIdUnique<'ctx> {
ActivitiesIdUnique {
imp: self.imp.get_unique_constraint::<u64>("id"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> ActivitiesIdUnique<'ctx> {
/// Find the subscribed row whose `id` column value is equal to `col_val`,
/// if such a row is present in the client cache.
pub fn find(&self, col_val: &u64) -> Option<Activity> {
self.imp.find(col_val)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<Activity>("activities");
_table.add_unique_constraint::<u64>("id", |row| &row.id);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<Activity>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<Activity>", "TableUpdate")
.with_cause(e)
.into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `Activity`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait activitiesQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `Activity`.
fn activities(&self) -> __sdk::__query_builder::Table<Activity>;
}
impl activitiesQueryTableAccess for __sdk::QueryTableAccessor {
fn activities(&self) -> __sdk::__query_builder::Table<Activity> {
__sdk::__query_builder::Table::new("activities")
}
}

View File

@@ -0,0 +1,58 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct Activity {
pub id: u64,
pub name: String,
pub task: Option<u64>,
pub parents_ids: Vec<u64>,
}
impl __sdk::InModule for Activity {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `Activity`.
///
/// Provides typed access to columns for query building.
pub struct ActivityCols {
pub id: __sdk::__query_builder::Col<Activity, u64>,
pub name: __sdk::__query_builder::Col<Activity, String>,
pub task: __sdk::__query_builder::Col<Activity, Option<u64>>,
pub parents_ids: __sdk::__query_builder::Col<Activity, Vec<u64>>,
}
impl __sdk::__query_builder::HasCols for Activity {
type Cols = ActivityCols;
fn cols(table_name: &'static str) -> Self::Cols {
ActivityCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
name: __sdk::__query_builder::Col::new(table_name, "name"),
task: __sdk::__query_builder::Col::new(table_name, "task"),
parents_ids: __sdk::__query_builder::Col::new(table_name, "parents_ids"),
}
}
}
/// Indexed column accessor struct for the table `Activity`.
///
/// Provides typed access to indexed columns for query building.
pub struct ActivityIxCols {
pub id: __sdk::__query_builder::IxCol<Activity, u64>,
}
impl __sdk::__query_builder::HasIxCols for Activity {
type IxCols = ActivityIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
ActivityIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for Activity {}

View File

@@ -0,0 +1,66 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub(super) struct AddActivityArgs {
pub name: String,
}
impl From<AddActivityArgs> for super::Reducer {
fn from(args: AddActivityArgs) -> Self {
Self::AddActivity { name: args.name }
}
}
impl __sdk::InModule for AddActivityArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `add_activity`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait add_activity {
/// Request that the remote module invoke the reducer `add_activity` to run as soon as possible.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and this method provides no way to listen for its completion status.
/// /// Use [`add_activity:add_activity_then`] to run a callback after the reducer completes.
fn add_activity(&self, name: String) -> __sdk::Result<()> {
self.add_activity_then(name, |_, _| {})
}
/// Request that the remote module invoke the reducer `add_activity` to run as soon as possible,
/// registering `callback` to run when we are notified that the reducer completed.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and its status can be observed with the `callback`.
fn add_activity_then(
&self,
name: String,
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
+ Send
+ 'static,
) -> __sdk::Result<()>;
}
impl add_activity for super::RemoteReducers {
fn add_activity_then(
&self,
name: String,
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
+ Send
+ 'static,
) -> __sdk::Result<()> {
self.imp
.invoke_reducer_with_callback(AddActivityArgs { name }, callback)
}
}

View File

@@ -0,0 +1,53 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::activity_type::Activity;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct Event {
pub start: __sdk::Timestamp,
pub end: __sdk::Timestamp,
pub activity: Activity,
}
impl __sdk::InModule for Event {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `Event`.
///
/// Provides typed access to columns for query building.
pub struct EventCols {
pub start: __sdk::__query_builder::Col<Event, __sdk::Timestamp>,
pub end: __sdk::__query_builder::Col<Event, __sdk::Timestamp>,
pub activity: __sdk::__query_builder::Col<Event, Activity>,
}
impl __sdk::__query_builder::HasCols for Event {
type Cols = EventCols;
fn cols(table_name: &'static str) -> Self::Cols {
EventCols {
start: __sdk::__query_builder::Col::new(table_name, "start"),
end: __sdk::__query_builder::Col::new(table_name, "end"),
activity: __sdk::__query_builder::Col::new(table_name, "activity"),
}
}
}
/// Indexed column accessor struct for the table `Event`.
///
/// Provides typed access to indexed columns for query building.
pub struct EventIxCols {}
impl __sdk::__query_builder::HasIxCols for Event {
type IxCols = EventIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
EventIxCols {}
}
}
impl __sdk::__query_builder::CanBeLookupTable for Event {}

View File

@@ -0,0 +1,112 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::activity_type::Activity;
use super::event_type::Event;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `events`.
///
/// Obtain a handle from the [`EventsTableAccess::events`] method on [`super::RemoteTables`],
/// like `ctx.db.events()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.events().on_insert(...)`.
pub struct EventsTableHandle<'ctx> {
imp: __sdk::TableHandle<Event>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `events`.
///
/// Implemented for [`super::RemoteTables`].
pub trait EventsTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`EventsTableHandle`], which mediates access to the table `events`.
fn events(&self) -> EventsTableHandle<'_>;
}
impl EventsTableAccess for super::RemoteTables {
fn events(&self) -> EventsTableHandle<'_> {
EventsTableHandle {
imp: self.imp.get_table::<Event>("events"),
ctx: std::marker::PhantomData,
}
}
}
pub struct EventsInsertCallbackId(__sdk::CallbackId);
pub struct EventsDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for EventsTableHandle<'ctx> {
type Row = Event;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = Event> + '_ {
self.imp.iter()
}
type InsertCallbackId = EventsInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> EventsInsertCallbackId {
EventsInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: EventsInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = EventsDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> EventsDeleteCallbackId {
EventsDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: EventsDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<Event>("events");
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<Event>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<Event>", "TableUpdate")
.with_cause(e)
.into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `Event`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait eventsQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `Event`.
fn events(&self) -> __sdk::__query_builder::Table<Event>;
}
impl eventsQueryTableAccess for __sdk::QueryTableAccessor {
fn events(&self) -> __sdk::__query_builder::Table<Event> {
__sdk::__query_builder::Table::new("events")
}
}

View File

@@ -1,28 +1,40 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
// This was generated using spacetimedb cli version 1.11.3 (commit 02449737ca3b29e7e39679fccbef541a50f32094).
// This was generated using spacetimedb cli version 2.1.0 (commit refs/tags/v2.1.0).
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
pub mod add_reducer;
pub mod identity_connected_reducer;
pub mod identity_disconnected_reducer;
pub mod person_table;
pub mod person_type;
pub mod say_hello_reducer;
pub mod activities_table;
pub mod activity_type;
pub mod add_activity_reducer;
pub mod event_type;
pub mod events_table;
pub mod profile_type;
pub mod profiles_table;
pub mod remove_activity_reducer;
pub mod set_activity_name_reducer;
pub mod task_part_table;
pub mod task_part_type;
pub mod task_type;
pub mod tasks_table;
pub mod update_activity_reducer;
pub use add_reducer::{add, set_flags_for_add, AddCallbackId};
pub use identity_connected_reducer::{
identity_connected, set_flags_for_identity_connected, IdentityConnectedCallbackId,
};
pub use identity_disconnected_reducer::{
identity_disconnected, set_flags_for_identity_disconnected, IdentityDisconnectedCallbackId,
};
pub use person_table::*;
pub use person_type::Person;
pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallbackId};
pub use activities_table::*;
pub use activity_type::Activity;
pub use add_activity_reducer::add_activity;
pub use event_type::Event;
pub use events_table::*;
pub use profile_type::Profile;
pub use profiles_table::*;
pub use remove_activity_reducer::remove_activity;
pub use set_activity_name_reducer::set_activity_name;
pub use task_part_table::*;
pub use task_part_type::TaskPart;
pub use task_type::Task;
pub use tasks_table::*;
pub use update_activity_reducer::update_activity;
#[derive(Clone, PartialEq, Debug)]
@@ -32,10 +44,10 @@ pub use say_hello_reducer::{say_hello, set_flags_for_say_hello, SayHelloCallback
/// to indicate which reducer caused the event.
pub enum Reducer {
Add { username: String },
IdentityConnected,
IdentityDisconnected,
SayHello,
AddActivity { name: String },
RemoveActivity { activity: Activity },
SetActivityName { id: u64, name: String },
UpdateActivity { activity: Activity },
}
impl __sdk::InModule for Reducer {
@@ -45,62 +57,72 @@ impl __sdk::InModule for Reducer {
impl __sdk::Reducer for Reducer {
fn reducer_name(&self) -> &'static str {
match self {
Reducer::Add { .. } => "add",
Reducer::IdentityConnected => "identity_connected",
Reducer::IdentityDisconnected => "identity_disconnected",
Reducer::SayHello => "say_hello",
Reducer::AddActivity { .. } => "add_activity",
Reducer::RemoveActivity { .. } => "remove_activity",
Reducer::SetActivityName { .. } => "set_activity_name",
Reducer::UpdateActivity { .. } => "update_activity",
_ => unreachable!(),
}
}
#[allow(clippy::clone_on_copy)]
fn args_bsatn(&self) -> Result<Vec<u8>, __sats::bsatn::EncodeError> {
match self {
Reducer::AddActivity { name } => {
__sats::bsatn::to_vec(&add_activity_reducer::AddActivityArgs { name: name.clone() })
}
Reducer::RemoveActivity { activity } => {
__sats::bsatn::to_vec(&remove_activity_reducer::RemoveActivityArgs {
activity: activity.clone(),
})
}
Reducer::SetActivityName { id, name } => {
__sats::bsatn::to_vec(&set_activity_name_reducer::SetActivityNameArgs {
id: id.clone(),
name: name.clone(),
})
}
Reducer::UpdateActivity { activity } => {
__sats::bsatn::to_vec(&update_activity_reducer::UpdateActivityArgs {
activity: activity.clone(),
})
}
_ => unreachable!(),
}
}
}
impl TryFrom<__ws::ReducerCallInfo<__ws::BsatnFormat>> for Reducer {
type Error = __sdk::Error;
fn try_from(value: __ws::ReducerCallInfo<__ws::BsatnFormat>) -> __sdk::Result<Self> {
match &value.reducer_name[..] {
"add" => {
Ok(__sdk::parse_reducer_args::<add_reducer::AddArgs>("add", &value.args)?.into())
}
"identity_connected" => Ok(__sdk::parse_reducer_args::<
identity_connected_reducer::IdentityConnectedArgs,
>("identity_connected", &value.args)?
.into()),
"identity_disconnected" => Ok(__sdk::parse_reducer_args::<
identity_disconnected_reducer::IdentityDisconnectedArgs,
>("identity_disconnected", &value.args)?
.into()),
"say_hello" => Ok(
__sdk::parse_reducer_args::<say_hello_reducer::SayHelloArgs>(
"say_hello",
&value.args,
)?
.into(),
),
unknown => {
Err(
__sdk::InternalError::unknown_name("reducer", unknown, "ReducerCallInfo")
.into(),
)
}
}
}
}
#[derive(Default)]
#[derive(Default, Debug)]
#[allow(non_snake_case)]
#[doc(hidden)]
pub struct DbUpdate {
person: __sdk::TableUpdate<Person>,
activities: __sdk::TableUpdate<Activity>,
events: __sdk::TableUpdate<Event>,
profiles: __sdk::TableUpdate<Profile>,
task_part: __sdk::TableUpdate<TaskPart>,
tasks: __sdk::TableUpdate<Task>,
}
impl TryFrom<__ws::DatabaseUpdate<__ws::BsatnFormat>> for DbUpdate {
impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
type Error = __sdk::Error;
fn try_from(raw: __ws::DatabaseUpdate<__ws::BsatnFormat>) -> Result<Self, Self::Error> {
fn try_from(raw: __ws::v2::TransactionUpdate) -> Result<Self, Self::Error> {
let mut db_update = DbUpdate::default();
for table_update in raw.tables {
for table_update in __sdk::transaction_update_iter_table_updates(raw) {
match &table_update.table_name[..] {
"person" => db_update
.person
.append(person_table::parse_table_update(table_update)?),
"activities" => db_update
.activities
.append(activities_table::parse_table_update(table_update)?),
"events" => db_update
.events
.append(events_table::parse_table_update(table_update)?),
"profiles" => db_update
.profiles
.append(profiles_table::parse_table_update(table_update)?),
"task_part" => db_update
.task_part
.append(task_part_table::parse_table_update(table_update)?),
"tasks" => db_update
.tasks
.append(tasks_table::parse_table_update(table_update)?),
unknown => {
return Err(__sdk::InternalError::unknown_name(
@@ -127,17 +149,89 @@ impl __sdk::DbUpdate for DbUpdate {
) -> AppliedDiff<'_> {
let mut diff = AppliedDiff::default();
diff.person = cache.apply_diff_to_table::<Person>("person", &self.person);
diff.activities = cache
.apply_diff_to_table::<Activity>("activities", &self.activities)
.with_updates_by_pk(|row| &row.id);
diff.events = cache.apply_diff_to_table::<Event>("events", &self.events);
diff.profiles = cache
.apply_diff_to_table::<Profile>("profiles", &self.profiles)
.with_updates_by_pk(|row| &row.identity);
diff.task_part = cache
.apply_diff_to_table::<TaskPart>("task_part", &self.task_part)
.with_updates_by_pk(|row| &row.identity);
diff.tasks = cache
.apply_diff_to_table::<Task>("tasks", &self.tasks)
.with_updates_by_pk(|row| &row.id);
diff
}
fn parse_initial_rows(raw: __ws::v2::QueryRows) -> __sdk::Result<Self> {
let mut db_update = DbUpdate::default();
for table_rows in raw.tables {
match &table_rows.table[..] {
"activities" => db_update
.activities
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"events" => db_update
.events
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"profiles" => db_update
.profiles
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"task_part" => db_update
.task_part
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"tasks" => db_update
.tasks
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
unknown => {
return Err(
__sdk::InternalError::unknown_name("table", unknown, "QueryRows").into(),
);
}
}
}
Ok(db_update)
}
fn parse_unsubscribe_rows(raw: __ws::v2::QueryRows) -> __sdk::Result<Self> {
let mut db_update = DbUpdate::default();
for table_rows in raw.tables {
match &table_rows.table[..] {
"activities" => db_update
.activities
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"events" => db_update
.events
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"profiles" => db_update
.profiles
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"task_part" => db_update
.task_part
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"tasks" => db_update
.tasks
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
unknown => {
return Err(
__sdk::InternalError::unknown_name("table", unknown, "QueryRows").into(),
);
}
}
}
Ok(db_update)
}
}
#[derive(Default)]
#[allow(non_snake_case)]
#[doc(hidden)]
pub struct AppliedDiff<'r> {
person: __sdk::TableAppliedDiff<'r, Person>,
activities: __sdk::TableAppliedDiff<'r, Activity>,
events: __sdk::TableAppliedDiff<'r, Event>,
profiles: __sdk::TableAppliedDiff<'r, Profile>,
task_part: __sdk::TableAppliedDiff<'r, TaskPart>,
tasks: __sdk::TableAppliedDiff<'r, Task>,
__unused: std::marker::PhantomData<&'r ()>,
}
@@ -151,11 +245,16 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
event: &EventContext,
callbacks: &mut __sdk::DbCallbacks<RemoteModule>,
) {
callbacks.invoke_table_row_callbacks::<Person>("person", &self.person, event);
callbacks.invoke_table_row_callbacks::<Activity>("activities", &self.activities, event);
callbacks.invoke_table_row_callbacks::<Event>("events", &self.events, event);
callbacks.invoke_table_row_callbacks::<Profile>("profiles", &self.profiles, event);
callbacks.invoke_table_row_callbacks::<TaskPart>("task_part", &self.task_part, event);
callbacks.invoke_table_row_callbacks::<Task>("tasks", &self.tasks, event);
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct RemoteModule;
impl __sdk::InModule for RemoteModule {
@@ -182,20 +281,6 @@ impl __sdk::InModule for RemoteProcedures {
type Module = RemoteModule;
}
#[doc(hidden)]
/// The `set_reducer_flags` field of [`DbConnection`],
/// with methods provided by extension traits for each reducer defined by the module.
/// Each method sets the flags for the reducer with the same name.
///
/// This type is currently unstable and may be removed without a major version bump.
pub struct SetReducerFlags {
imp: __sdk::DbContextImpl<RemoteModule>,
}
impl __sdk::InModule for SetReducerFlags {
type Module = RemoteModule;
}
/// The `db` field of [`EventContext`] and [`DbConnection`],
/// with methods provided by extension traits for each table defined by the module.
pub struct RemoteTables {
@@ -214,10 +299,17 @@ impl __sdk::InModule for RemoteTables {
/// You must explicitly advance the connection by calling any one of:
///
/// - [`DbConnection::frame_tick`].
/// - [`DbConnection::run_threaded`].
#[cfg_attr(not(target_arch = "wasm32"), doc = "- [`DbConnection::run_threaded`].")]
#[cfg_attr(
target_arch = "wasm32",
doc = "- [`DbConnection::run_background_task`]."
)]
/// - [`DbConnection::run_async`].
/// - [`DbConnection::advance_one_message`].
/// - [`DbConnection::advance_one_message_blocking`].
#[cfg_attr(
not(target_arch = "wasm32"),
doc = "- [`DbConnection::advance_one_message_blocking`]."
)]
/// - [`DbConnection::advance_one_message_async`].
///
/// Which of these methods you should call depends on the specific needs of your application,
@@ -228,11 +320,6 @@ pub struct DbConnection {
/// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`].
pub reducers: RemoteReducers,
#[doc(hidden)]
/// Access to setting the call-flags of each reducer defined for each reducer defined by the module
/// via extension traits implemented for [`SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub set_reducer_flags: SetReducerFlags,
/// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`].
pub procedures: RemoteProcedures,
@@ -248,7 +335,6 @@ impl __sdk::DbContext for DbConnection {
type DbView = RemoteTables;
type Reducers = RemoteReducers;
type Procedures = RemoteProcedures;
type SetReducerFlags = SetReducerFlags;
fn db(&self) -> &Self::DbView {
&self.db
@@ -259,9 +345,6 @@ impl __sdk::DbContext for DbConnection {
fn procedures(&self) -> &Self::Procedures {
&self.procedures
}
fn set_reducer_flags(&self) -> &Self::SetReducerFlags {
&self.set_reducer_flags
}
fn is_active(&self) -> bool {
self.imp.is_active()
@@ -324,6 +407,7 @@ impl DbConnection {
/// This is a low-level primitive exposed for power users who need significant control over scheduling.
/// Most applications should call [`Self::run_threaded`] to spawn a thread
/// which advances the connection automatically.
#[cfg(not(target_arch = "wasm32"))]
pub fn advance_one_message_blocking(&self) -> __sdk::Result<()> {
self.imp.advance_one_message_blocking()
}
@@ -349,10 +433,17 @@ impl DbConnection {
}
/// Spawn a thread which processes WebSocket messages as they are received.
#[cfg(not(target_arch = "wasm32"))]
pub fn run_threaded(&self) -> std::thread::JoinHandle<()> {
self.imp.run_threaded()
}
/// Spawn a background task which processes WebSocket messages as they are received.
#[cfg(target_arch = "wasm32")]
pub fn run_background_task(&self) {
self.imp.run_background_task()
}
/// Run an `async` loop which processes WebSocket messages when polled.
pub async fn run_async(&self) -> __sdk::Result<()> {
self.imp.run_async().await
@@ -365,7 +456,6 @@ impl __sdk::DbConnection for DbConnection {
db: RemoteTables { imp: imp.clone() },
reducers: RemoteReducers { imp: imp.clone() },
procedures: RemoteProcedures { imp: imp.clone() },
set_reducer_flags: SetReducerFlags { imp: imp.clone() },
imp,
}
}
@@ -417,7 +507,6 @@ pub trait RemoteDbContext:
__sdk::DbContext<
DbView = RemoteTables,
Reducers = RemoteReducers,
SetReducerFlags = SetReducerFlags,
SubscriptionBuilder = __sdk::SubscriptionBuilder<RemoteModule>,
>
{
@@ -426,7 +515,6 @@ impl<
Ctx: __sdk::DbContext<
DbView = RemoteTables,
Reducers = RemoteReducers,
SetReducerFlags = SetReducerFlags,
SubscriptionBuilder = __sdk::SubscriptionBuilder<RemoteModule>,
>,
> RemoteDbContext for Ctx
@@ -440,11 +528,6 @@ pub struct EventContext {
pub db: RemoteTables,
/// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`].
pub reducers: RemoteReducers,
/// Access to setting the call-flags of each reducer defined for each reducer defined by the module
/// via extension traits implemented for [`SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub set_reducer_flags: SetReducerFlags,
/// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`].
pub procedures: RemoteProcedures,
/// The event which caused these callbacks to run.
@@ -461,7 +544,6 @@ impl __sdk::AbstractEventContext for EventContext {
Self {
db: RemoteTables { imp: imp.clone() },
reducers: RemoteReducers { imp: imp.clone() },
set_reducer_flags: SetReducerFlags { imp: imp.clone() },
procedures: RemoteProcedures { imp: imp.clone() },
event,
imp,
@@ -477,7 +559,6 @@ impl __sdk::DbContext for EventContext {
type DbView = RemoteTables;
type Reducers = RemoteReducers;
type Procedures = RemoteProcedures;
type SetReducerFlags = SetReducerFlags;
fn db(&self) -> &Self::DbView {
&self.db
@@ -488,9 +569,6 @@ impl __sdk::DbContext for EventContext {
fn procedures(&self) -> &Self::Procedures {
&self.procedures
}
fn set_reducer_flags(&self) -> &Self::SetReducerFlags {
&self.set_reducer_flags
}
fn is_active(&self) -> bool {
self.imp.is_active()
@@ -526,11 +604,6 @@ pub struct ReducerEventContext {
pub db: RemoteTables,
/// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`].
pub reducers: RemoteReducers,
/// Access to setting the call-flags of each reducer defined for each reducer defined by the module
/// via extension traits implemented for [`SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub set_reducer_flags: SetReducerFlags,
/// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`].
pub procedures: RemoteProcedures,
/// The event which caused these callbacks to run.
@@ -547,7 +620,6 @@ impl __sdk::AbstractEventContext for ReducerEventContext {
Self {
db: RemoteTables { imp: imp.clone() },
reducers: RemoteReducers { imp: imp.clone() },
set_reducer_flags: SetReducerFlags { imp: imp.clone() },
procedures: RemoteProcedures { imp: imp.clone() },
event,
imp,
@@ -563,7 +635,6 @@ impl __sdk::DbContext for ReducerEventContext {
type DbView = RemoteTables;
type Reducers = RemoteReducers;
type Procedures = RemoteProcedures;
type SetReducerFlags = SetReducerFlags;
fn db(&self) -> &Self::DbView {
&self.db
@@ -574,9 +645,6 @@ impl __sdk::DbContext for ReducerEventContext {
fn procedures(&self) -> &Self::Procedures {
&self.procedures
}
fn set_reducer_flags(&self) -> &Self::SetReducerFlags {
&self.set_reducer_flags
}
fn is_active(&self) -> bool {
self.imp.is_active()
@@ -611,11 +679,6 @@ pub struct ProcedureEventContext {
pub db: RemoteTables,
/// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`].
pub reducers: RemoteReducers,
/// Access to setting the call-flags of each reducer defined for each reducer defined by the module
/// via extension traits implemented for [`SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub set_reducer_flags: SetReducerFlags,
/// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`].
pub procedures: RemoteProcedures,
imp: __sdk::DbContextImpl<RemoteModule>,
@@ -631,7 +694,6 @@ impl __sdk::AbstractEventContext for ProcedureEventContext {
db: RemoteTables { imp: imp.clone() },
reducers: RemoteReducers { imp: imp.clone() },
procedures: RemoteProcedures { imp: imp.clone() },
set_reducer_flags: SetReducerFlags { imp: imp.clone() },
imp,
}
}
@@ -645,7 +707,6 @@ impl __sdk::DbContext for ProcedureEventContext {
type DbView = RemoteTables;
type Reducers = RemoteReducers;
type Procedures = RemoteProcedures;
type SetReducerFlags = SetReducerFlags;
fn db(&self) -> &Self::DbView {
&self.db
@@ -656,9 +717,6 @@ impl __sdk::DbContext for ProcedureEventContext {
fn procedures(&self) -> &Self::Procedures {
&self.procedures
}
fn set_reducer_flags(&self) -> &Self::SetReducerFlags {
&self.set_reducer_flags
}
fn is_active(&self) -> bool {
self.imp.is_active()
@@ -693,11 +751,6 @@ pub struct SubscriptionEventContext {
pub db: RemoteTables,
/// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`].
pub reducers: RemoteReducers,
/// Access to setting the call-flags of each reducer defined for each reducer defined by the module
/// via extension traits implemented for [`SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub set_reducer_flags: SetReducerFlags,
/// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`].
pub procedures: RemoteProcedures,
imp: __sdk::DbContextImpl<RemoteModule>,
@@ -713,7 +766,6 @@ impl __sdk::AbstractEventContext for SubscriptionEventContext {
db: RemoteTables { imp: imp.clone() },
reducers: RemoteReducers { imp: imp.clone() },
procedures: RemoteProcedures { imp: imp.clone() },
set_reducer_flags: SetReducerFlags { imp: imp.clone() },
imp,
}
}
@@ -727,7 +779,6 @@ impl __sdk::DbContext for SubscriptionEventContext {
type DbView = RemoteTables;
type Reducers = RemoteReducers;
type Procedures = RemoteProcedures;
type SetReducerFlags = SetReducerFlags;
fn db(&self) -> &Self::DbView {
&self.db
@@ -738,9 +789,6 @@ impl __sdk::DbContext for SubscriptionEventContext {
fn procedures(&self) -> &Self::Procedures {
&self.procedures
}
fn set_reducer_flags(&self) -> &Self::SetReducerFlags {
&self.set_reducer_flags
}
fn is_active(&self) -> bool {
self.imp.is_active()
@@ -776,11 +824,6 @@ pub struct ErrorContext {
pub db: RemoteTables,
/// Access to reducers defined by the module via extension traits implemented for [`RemoteReducers`].
pub reducers: RemoteReducers,
/// Access to setting the call-flags of each reducer defined for each reducer defined by the module
/// via extension traits implemented for [`SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub set_reducer_flags: SetReducerFlags,
/// Access to procedures defined by the module via extension traits implemented for [`RemoteProcedures`].
pub procedures: RemoteProcedures,
/// The event which caused these callbacks to run.
@@ -797,7 +840,6 @@ impl __sdk::AbstractEventContext for ErrorContext {
Self {
db: RemoteTables { imp: imp.clone() },
reducers: RemoteReducers { imp: imp.clone() },
set_reducer_flags: SetReducerFlags { imp: imp.clone() },
procedures: RemoteProcedures { imp: imp.clone() },
event,
imp,
@@ -813,7 +855,6 @@ impl __sdk::DbContext for ErrorContext {
type DbView = RemoteTables;
type Reducers = RemoteReducers;
type Procedures = RemoteProcedures;
type SetReducerFlags = SetReducerFlags;
fn db(&self) -> &Self::DbView {
&self.db
@@ -824,9 +865,6 @@ impl __sdk::DbContext for ErrorContext {
fn procedures(&self) -> &Self::Procedures {
&self.procedures
}
fn set_reducer_flags(&self) -> &Self::SetReducerFlags {
&self.set_reducer_flags
}
fn is_active(&self) -> bool {
self.imp.is_active()
@@ -865,12 +903,19 @@ impl __sdk::SpacetimeModule for RemoteModule {
type Reducer = Reducer;
type DbView = RemoteTables;
type Reducers = RemoteReducers;
type SetReducerFlags = SetReducerFlags;
type Procedures = RemoteProcedures;
type DbUpdate = DbUpdate;
type AppliedDiff<'r> = AppliedDiff<'r>;
type SubscriptionHandle = SubscriptionHandle;
type QueryBuilder = __sdk::QueryBuilder;
fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
person_table::register_table(client_cache);
activities_table::register_table(client_cache);
events_table::register_table(client_cache);
profiles_table::register_table(client_cache);
task_part_table::register_table(client_cache);
tasks_table::register_table(client_cache);
}
const ALL_TABLE_NAMES: &'static [&'static str] =
&["activities", "events", "profiles", "task_part", "tasks"];
}

View File

@@ -0,0 +1,54 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct Profile {
pub identity: __sdk::Identity,
pub username: String,
}
impl __sdk::InModule for Profile {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `Profile`.
///
/// Provides typed access to columns for query building.
pub struct ProfileCols {
pub identity: __sdk::__query_builder::Col<Profile, __sdk::Identity>,
pub username: __sdk::__query_builder::Col<Profile, String>,
}
impl __sdk::__query_builder::HasCols for Profile {
type Cols = ProfileCols;
fn cols(table_name: &'static str) -> Self::Cols {
ProfileCols {
identity: __sdk::__query_builder::Col::new(table_name, "identity"),
username: __sdk::__query_builder::Col::new(table_name, "username"),
}
}
}
/// Indexed column accessor struct for the table `Profile`.
///
/// Provides typed access to indexed columns for query building.
pub struct ProfileIxCols {
pub identity: __sdk::__query_builder::IxCol<Profile, __sdk::Identity>,
pub username: __sdk::__query_builder::IxCol<Profile, String>,
}
impl __sdk::__query_builder::HasIxCols for Profile {
type IxCols = ProfileIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
ProfileIxCols {
identity: __sdk::__query_builder::IxCol::new(table_name, "identity"),
username: __sdk::__query_builder::IxCol::new(table_name, "username"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for Profile {}

View File

@@ -0,0 +1,192 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::profile_type::Profile;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `profiles`.
///
/// Obtain a handle from the [`ProfilesTableAccess::profiles`] method on [`super::RemoteTables`],
/// like `ctx.db.profiles()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.profiles().on_insert(...)`.
pub struct ProfilesTableHandle<'ctx> {
imp: __sdk::TableHandle<Profile>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `profiles`.
///
/// Implemented for [`super::RemoteTables`].
pub trait ProfilesTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`ProfilesTableHandle`], which mediates access to the table `profiles`.
fn profiles(&self) -> ProfilesTableHandle<'_>;
}
impl ProfilesTableAccess for super::RemoteTables {
fn profiles(&self) -> ProfilesTableHandle<'_> {
ProfilesTableHandle {
imp: self.imp.get_table::<Profile>("profiles"),
ctx: std::marker::PhantomData,
}
}
}
pub struct ProfilesInsertCallbackId(__sdk::CallbackId);
pub struct ProfilesDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for ProfilesTableHandle<'ctx> {
type Row = Profile;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = Profile> + '_ {
self.imp.iter()
}
type InsertCallbackId = ProfilesInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> ProfilesInsertCallbackId {
ProfilesInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: ProfilesInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = ProfilesDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> ProfilesDeleteCallbackId {
ProfilesDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: ProfilesDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct ProfilesUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for ProfilesTableHandle<'ctx> {
type UpdateCallbackId = ProfilesUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> ProfilesUpdateCallbackId {
ProfilesUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: ProfilesUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `identity` unique index on the table `profiles`,
/// which allows point queries on the field of the same name
/// via the [`ProfilesIdentityUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.profiles().identity().find(...)`.
pub struct ProfilesIdentityUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<Profile, __sdk::Identity>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> ProfilesTableHandle<'ctx> {
/// Get a handle on the `identity` unique index on the table `profiles`.
pub fn identity(&self) -> ProfilesIdentityUnique<'ctx> {
ProfilesIdentityUnique {
imp: self
.imp
.get_unique_constraint::<__sdk::Identity>("identity"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> ProfilesIdentityUnique<'ctx> {
/// Find the subscribed row whose `identity` column value is equal to `col_val`,
/// if such a row is present in the client cache.
pub fn find(&self, col_val: &__sdk::Identity) -> Option<Profile> {
self.imp.find(col_val)
}
}
/// Access to the `username` unique index on the table `profiles`,
/// which allows point queries on the field of the same name
/// via the [`ProfilesUsernameUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.profiles().username().find(...)`.
pub struct ProfilesUsernameUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<Profile, String>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> ProfilesTableHandle<'ctx> {
/// Get a handle on the `username` unique index on the table `profiles`.
pub fn username(&self) -> ProfilesUsernameUnique<'ctx> {
ProfilesUsernameUnique {
imp: self.imp.get_unique_constraint::<String>("username"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> ProfilesUsernameUnique<'ctx> {
/// Find the subscribed row whose `username` column value is equal to `col_val`,
/// if such a row is present in the client cache.
pub fn find(&self, col_val: &String) -> Option<Profile> {
self.imp.find(col_val)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<Profile>("profiles");
_table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity);
_table.add_unique_constraint::<String>("username", |row| &row.username);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<Profile>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<Profile>", "TableUpdate")
.with_cause(e)
.into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `Profile`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait profilesQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `Profile`.
fn profiles(&self) -> __sdk::__query_builder::Table<Profile>;
}
impl profilesQueryTableAccess for __sdk::QueryTableAccessor {
fn profiles(&self) -> __sdk::__query_builder::Table<Profile> {
__sdk::__query_builder::Table::new("profiles")
}
}

View File

@@ -0,0 +1,70 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::activity_type::Activity;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub(super) struct RemoveActivityArgs {
pub activity: Activity,
}
impl From<RemoveActivityArgs> for super::Reducer {
fn from(args: RemoveActivityArgs) -> Self {
Self::RemoveActivity {
activity: args.activity,
}
}
}
impl __sdk::InModule for RemoveActivityArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `remove_activity`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait remove_activity {
/// Request that the remote module invoke the reducer `remove_activity` to run as soon as possible.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and this method provides no way to listen for its completion status.
/// /// Use [`remove_activity:remove_activity_then`] to run a callback after the reducer completes.
fn remove_activity(&self, activity: Activity) -> __sdk::Result<()> {
self.remove_activity_then(activity, |_, _| {})
}
/// Request that the remote module invoke the reducer `remove_activity` to run as soon as possible,
/// registering `callback` to run when we are notified that the reducer completed.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and its status can be observed with the `callback`.
fn remove_activity_then(
&self,
activity: Activity,
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
+ Send
+ 'static,
) -> __sdk::Result<()>;
}
impl remove_activity for super::RemoteReducers {
fn remove_activity_then(
&self,
activity: Activity,
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
+ Send
+ 'static,
) -> __sdk::Result<()> {
self.imp
.invoke_reducer_with_callback(RemoveActivityArgs { activity }, callback)
}
}

View File

@@ -0,0 +1,72 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub(super) struct SetActivityNameArgs {
pub id: u64,
pub name: String,
}
impl From<SetActivityNameArgs> for super::Reducer {
fn from(args: SetActivityNameArgs) -> Self {
Self::SetActivityName {
id: args.id,
name: args.name,
}
}
}
impl __sdk::InModule for SetActivityNameArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `set_activity_name`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait set_activity_name {
/// Request that the remote module invoke the reducer `set_activity_name` to run as soon as possible.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and this method provides no way to listen for its completion status.
/// /// Use [`set_activity_name:set_activity_name_then`] to run a callback after the reducer completes.
fn set_activity_name(&self, id: u64, name: String) -> __sdk::Result<()> {
self.set_activity_name_then(id, name, |_, _| {})
}
/// Request that the remote module invoke the reducer `set_activity_name` to run as soon as possible,
/// registering `callback` to run when we are notified that the reducer completed.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and its status can be observed with the `callback`.
fn set_activity_name_then(
&self,
id: u64,
name: String,
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
+ Send
+ 'static,
) -> __sdk::Result<()>;
}
impl set_activity_name for super::RemoteReducers {
fn set_activity_name_then(
&self,
id: u64,
name: String,
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
+ Send
+ 'static,
) -> __sdk::Result<()> {
self.imp
.invoke_reducer_with_callback(SetActivityNameArgs { id, name }, callback)
}
}

View File

@@ -0,0 +1,162 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::activity_type::Activity;
use super::task_part_type::TaskPart;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `task_part`.
///
/// Obtain a handle from the [`TaskPartTableAccess::task_part`] method on [`super::RemoteTables`],
/// like `ctx.db.task_part()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.task_part().on_insert(...)`.
pub struct TaskPartTableHandle<'ctx> {
imp: __sdk::TableHandle<TaskPart>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `task_part`.
///
/// Implemented for [`super::RemoteTables`].
pub trait TaskPartTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`TaskPartTableHandle`], which mediates access to the table `task_part`.
fn task_part(&self) -> TaskPartTableHandle<'_>;
}
impl TaskPartTableAccess for super::RemoteTables {
fn task_part(&self) -> TaskPartTableHandle<'_> {
TaskPartTableHandle {
imp: self.imp.get_table::<TaskPart>("task_part"),
ctx: std::marker::PhantomData,
}
}
}
pub struct TaskPartInsertCallbackId(__sdk::CallbackId);
pub struct TaskPartDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for TaskPartTableHandle<'ctx> {
type Row = TaskPart;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = TaskPart> + '_ {
self.imp.iter()
}
type InsertCallbackId = TaskPartInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> TaskPartInsertCallbackId {
TaskPartInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: TaskPartInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = TaskPartDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> TaskPartDeleteCallbackId {
TaskPartDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: TaskPartDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct TaskPartUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for TaskPartTableHandle<'ctx> {
type UpdateCallbackId = TaskPartUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> TaskPartUpdateCallbackId {
TaskPartUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: TaskPartUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `identity` unique index on the table `task_part`,
/// which allows point queries on the field of the same name
/// via the [`TaskPartIdentityUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.task_part().identity().find(...)`.
pub struct TaskPartIdentityUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<TaskPart, __sdk::Identity>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> TaskPartTableHandle<'ctx> {
/// Get a handle on the `identity` unique index on the table `task_part`.
pub fn identity(&self) -> TaskPartIdentityUnique<'ctx> {
TaskPartIdentityUnique {
imp: self
.imp
.get_unique_constraint::<__sdk::Identity>("identity"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> TaskPartIdentityUnique<'ctx> {
/// Find the subscribed row whose `identity` column value is equal to `col_val`,
/// if such a row is present in the client cache.
pub fn find(&self, col_val: &__sdk::Identity) -> Option<TaskPart> {
self.imp.find(col_val)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<TaskPart>("task_part");
_table.add_unique_constraint::<__sdk::Identity>("identity", |row| &row.identity);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<TaskPart>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<TaskPart>", "TableUpdate")
.with_cause(e)
.into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `TaskPart`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait task_partQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `TaskPart`.
fn task_part(&self) -> __sdk::__query_builder::Table<TaskPart>;
}
impl task_partQueryTableAccess for __sdk::QueryTableAccessor {
fn task_part(&self) -> __sdk::__query_builder::Table<TaskPart> {
__sdk::__query_builder::Table::new("task_part")
}
}

View File

@@ -0,0 +1,54 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::activity_type::Activity;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct TaskPart {
pub identity: __sdk::Identity,
pub current_activity: Activity,
}
impl __sdk::InModule for TaskPart {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `TaskPart`.
///
/// Provides typed access to columns for query building.
pub struct TaskPartCols {
pub identity: __sdk::__query_builder::Col<TaskPart, __sdk::Identity>,
pub current_activity: __sdk::__query_builder::Col<TaskPart, Activity>,
}
impl __sdk::__query_builder::HasCols for TaskPart {
type Cols = TaskPartCols;
fn cols(table_name: &'static str) -> Self::Cols {
TaskPartCols {
identity: __sdk::__query_builder::Col::new(table_name, "identity"),
current_activity: __sdk::__query_builder::Col::new(table_name, "current_activity"),
}
}
}
/// Indexed column accessor struct for the table `TaskPart`.
///
/// Provides typed access to indexed columns for query building.
pub struct TaskPartIxCols {
pub identity: __sdk::__query_builder::IxCol<TaskPart, __sdk::Identity>,
}
impl __sdk::__query_builder::HasIxCols for TaskPart {
type IxCols = TaskPartIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
TaskPartIxCols {
identity: __sdk::__query_builder::IxCol::new(table_name, "identity"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for TaskPart {}

View File

@@ -0,0 +1,58 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct Task {
pub id: u64,
pub done: bool,
pub name: String,
pub parent: Option<u64>,
}
impl __sdk::InModule for Task {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `Task`.
///
/// Provides typed access to columns for query building.
pub struct TaskCols {
pub id: __sdk::__query_builder::Col<Task, u64>,
pub done: __sdk::__query_builder::Col<Task, bool>,
pub name: __sdk::__query_builder::Col<Task, String>,
pub parent: __sdk::__query_builder::Col<Task, Option<u64>>,
}
impl __sdk::__query_builder::HasCols for Task {
type Cols = TaskCols;
fn cols(table_name: &'static str) -> Self::Cols {
TaskCols {
id: __sdk::__query_builder::Col::new(table_name, "id"),
done: __sdk::__query_builder::Col::new(table_name, "done"),
name: __sdk::__query_builder::Col::new(table_name, "name"),
parent: __sdk::__query_builder::Col::new(table_name, "parent"),
}
}
}
/// Indexed column accessor struct for the table `Task`.
///
/// Provides typed access to indexed columns for query building.
pub struct TaskIxCols {
pub id: __sdk::__query_builder::IxCol<Task, u64>,
}
impl __sdk::__query_builder::HasIxCols for Task {
type IxCols = TaskIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
TaskIxCols {
id: __sdk::__query_builder::IxCol::new(table_name, "id"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for Task {}

View File

@@ -0,0 +1,159 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::task_type::Task;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `tasks`.
///
/// Obtain a handle from the [`TasksTableAccess::tasks`] method on [`super::RemoteTables`],
/// like `ctx.db.tasks()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.tasks().on_insert(...)`.
pub struct TasksTableHandle<'ctx> {
imp: __sdk::TableHandle<Task>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `tasks`.
///
/// Implemented for [`super::RemoteTables`].
pub trait TasksTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`TasksTableHandle`], which mediates access to the table `tasks`.
fn tasks(&self) -> TasksTableHandle<'_>;
}
impl TasksTableAccess for super::RemoteTables {
fn tasks(&self) -> TasksTableHandle<'_> {
TasksTableHandle {
imp: self.imp.get_table::<Task>("tasks"),
ctx: std::marker::PhantomData,
}
}
}
pub struct TasksInsertCallbackId(__sdk::CallbackId);
pub struct TasksDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for TasksTableHandle<'ctx> {
type Row = Task;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = Task> + '_ {
self.imp.iter()
}
type InsertCallbackId = TasksInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> TasksInsertCallbackId {
TasksInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: TasksInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = TasksDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> TasksDeleteCallbackId {
TasksDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: TasksDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct TasksUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for TasksTableHandle<'ctx> {
type UpdateCallbackId = TasksUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> TasksUpdateCallbackId {
TasksUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: TasksUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `id` unique index on the table `tasks`,
/// which allows point queries on the field of the same name
/// via the [`TasksIdUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.tasks().id().find(...)`.
pub struct TasksIdUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<Task, u64>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> TasksTableHandle<'ctx> {
/// Get a handle on the `id` unique index on the table `tasks`.
pub fn id(&self) -> TasksIdUnique<'ctx> {
TasksIdUnique {
imp: self.imp.get_unique_constraint::<u64>("id"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> TasksIdUnique<'ctx> {
/// Find the subscribed row whose `id` column value is equal to `col_val`,
/// if such a row is present in the client cache.
pub fn find(&self, col_val: &u64) -> Option<Task> {
self.imp.find(col_val)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<Task>("tasks");
_table.add_unique_constraint::<u64>("id", |row| &row.id);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<Task>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<Task>", "TableUpdate")
.with_cause(e)
.into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `Task`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait tasksQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `Task`.
fn tasks(&self) -> __sdk::__query_builder::Table<Task>;
}
impl tasksQueryTableAccess for __sdk::QueryTableAccessor {
fn tasks(&self) -> __sdk::__query_builder::Table<Task> {
__sdk::__query_builder::Table::new("tasks")
}
}

View File

@@ -0,0 +1,70 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::activity_type::Activity;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub(super) struct UpdateActivityArgs {
pub activity: Activity,
}
impl From<UpdateActivityArgs> for super::Reducer {
fn from(args: UpdateActivityArgs) -> Self {
Self::UpdateActivity {
activity: args.activity,
}
}
}
impl __sdk::InModule for UpdateActivityArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `update_activity`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait update_activity {
/// Request that the remote module invoke the reducer `update_activity` to run as soon as possible.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and this method provides no way to listen for its completion status.
/// /// Use [`update_activity:update_activity_then`] to run a callback after the reducer completes.
fn update_activity(&self, activity: Activity) -> __sdk::Result<()> {
self.update_activity_then(activity, |_, _| {})
}
/// Request that the remote module invoke the reducer `update_activity` to run as soon as possible,
/// registering `callback` to run when we are notified that the reducer completed.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and its status can be observed with the `callback`.
fn update_activity_then(
&self,
activity: Activity,
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
+ Send
+ 'static,
) -> __sdk::Result<()>;
}
impl update_activity for super::RemoteReducers {
fn update_activity_then(
&self,
activity: Activity,
callback: impl FnOnce(&super::ReducerEventContext, Result<Result<(), String>, __sdk::InternalError>)
+ Send
+ 'static,
) -> __sdk::Result<()> {
self.imp
.invoke_reducer_with_callback(UpdateActivityArgs { activity }, callback)
}
}

View File

@@ -1,3 +1,5 @@
#![feature(oneshot_channel)]
mod platform {
#[cfg(feature = "target-obsidian")]
pub mod obsidian;
@@ -21,3 +23,10 @@ pub mod auth {
pub mod client;
}
pub use auth::client::client_auth;
pub mod spacetime;
pub mod timetrack;
// the generated source
// right now only from spacetimedb
mod generated;

View File

@@ -17,12 +17,34 @@ fn main() {
#[cfg(feature = "target-os")]
fn os_main(mize: &mut Mize) -> MizeResult<()> {
use ppc::spacetime::spacetime;
marts::cli(mize)?;
//marts::js(mize)?;
marts::habitica(mize)?;
#[cfg(feature = "client")]
{
use ppc::timetrack::timetrack;
ppc::client_auth(mize)?;
if let Err(err) = spacetime(mize) {
println!("spacetime part failed to initialize: {:?}", err);
};
timetrack(mize)?;
}
//marts::habitica(mize)?;
marts::c2vi(mize)?;
#[cfg(feature = "server")]
ppc::server(mize)?;
ppc::client_auth(mize)?;
#[cfg(feature = "client")]
#[cfg(feature = "desktop")]
cli.subcommand(Command::new("gui"), |_, _| {
ppc::ui::launch_desktop_app();
Ok(())
});
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
@@ -31,7 +53,7 @@ fn os_main(mize: &mut Mize) -> MizeResult<()> {
.version(crate_version!())
.name("ppc")
.author("ppc")
.about("the ppc desktop program"))
.about("the ppc app"))
})?;
cli.subcommand(Command::new("test"), |_, _| {
@@ -39,11 +61,6 @@ fn os_main(mize: &mut Mize) -> MizeResult<()> {
Ok(())
});
cli.subcommand(Command::new("gui"), |_, _| {
ppc::ui::launch_desktop_app();
Ok(())
});
drop(cli);
mize.run()
}

View File

@@ -54,6 +54,9 @@ pub fn server(mize: &mut Mize) -> MizeResult<()> {
pub async fn start_server(mize: &mut Mize) -> MizeResult<()> {
dioxus::logger::initialize_default();
let issuer = mize.get_config("auth.issuer")?.value_string()?;
let listen_addr = mize.get_config("server.listen_addr")?.value_string()?;
let port = mize.get_config("server.port")?.value_string()?;
let issuer = mize.get_config("auth.issuer")?.value_string()?;
let client_id = mize.get_config("auth.client_id")?.value_string()?;
let client_secret = mize.get_config("auth.client_secret")?.value_string()?;
@@ -107,9 +110,11 @@ pub async fn start_server(mize: &mut Mize) -> MizeResult<()> {
.route("/", get(ppc_main_page))
.route("/oidc_display_code_and_state", get(display_code_and_state));
tracing::info!("Running on http://localhost:3000");
tracing::info!("Running on http://{listen_addr}:{port}");
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
let listener = tokio::net::TcpListener::bind(format!("{listen_addr}:{port}"))
.await
.unwrap();
axum::serve(listener, app.into_make_service())
.await
.unwrap();

44
packages/ppc/spacetime.rs Normal file
View File

@@ -0,0 +1,44 @@
use mize::{Mize, MizeError, MizePart, MizeResult, mize_part};
use crate::{auth::client::ClientAuth, generated::DbConnection};
#[mize_part]
#[derive(Default)]
pub struct SpacetimePart {
mize: Mize,
con: Option<DbConnection>,
}
impl MizePart for SpacetimePart {
fn name(&self) -> &'static str {
"spacetime"
}
}
impl SpacetimePart {
pub fn con(&mut self) -> &mut DbConnection {
self.con.as_mut().unwrap()
}
}
pub fn spacetime(mize: &mut Mize) -> MizeResult<()> {
let auth = mize.get_part_native::<ClientAuth>("client_auth")?;
let db_url = mize.get_config("spacetime.url")?.value_string()?;
let con = DbConnection::builder()
.with_token(Some(auth.id_token()?))
.with_database_name("ppc")
.with_uri(db_url)
//.on_connect(callback)
//.on_disconnect(callback)
//.on_connect_error(callback)
//.with_compression(...)
.build()?;
con.run_threaded();
mize.register_part(Box::new(SpacetimePart {
mize: mize.clone(),
con: Some(con),
}))
}

View File

@@ -1,5 +1,5 @@
[package]
name = "quickstart_chat"
name = "ppc-spacetime"
version = "0.1.0"
edition = "2021"

View File

@@ -9,6 +9,13 @@ pub struct Profile {
username: String,
}
#[table(accessor = task_part, public)]
pub struct TaskPart {
#[primary_key]
identity: Identity,
current_activity: Activity,
}
#[table(accessor = activities, public)]
pub struct Activity {
#[primary_key]
@@ -16,6 +23,7 @@ pub struct Activity {
id: u64,
name: String,
task: Option<u64>,
parents_ids: Vec<u64>,
}
#[table(accessor = tasks, public)]
@@ -85,5 +93,29 @@ pub fn add_activity(ctx: &ReducerContext, name: String) {
name,
task: None,
id: 0, // auto-increments
parents_ids: Vec::new(),
});
}
#[reducer]
pub fn set_activity_name(ctx: &ReducerContext, id: u64, name: String) {
if let Some(old_ac) = ctx.db.activities().id().find(id) {
ctx.db.activities().id().update(Activity { name, ..old_ac });
} else {
return ();
}
}
#[reducer]
pub fn update_activity(ctx: &ReducerContext, activity: Activity) {
if activity.id == 0 {
ctx.db.activities().insert(activity);
} else {
ctx.db.activities().id().update(activity);
}
}
#[reducer]
pub fn remove_activity(ctx: &ReducerContext, activity: Activity) {
ctx.db.activities().delete(activity);
}

View File

@@ -0,0 +1,257 @@
use std::{io::Read, sync::oneshot, thread, time::Duration};
use clap::{ArgMatches, Command};
use mize::{Mize, MizeError, MizePart, MizePartGuard, MizeResult, mize_err, mize_part};
use spacetimedb_sdk::{
DbContext, Error, Event, Identity, Status, SubscriptionHandle, Table, TableWithPrimaryKey,
credentials,
};
use crate::{
generated::{
ActivitiesTableAccess, Activity, DbConnection, activitiesQueryTableAccess, remove_activity,
update_activity,
},
spacetime::SpacetimePart,
};
#[mize_part]
#[derive(Default)]
pub struct TimeTrack {
mize: Mize,
}
pub fn timetrack(mize: &mut Mize) -> MizeResult<()> {
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
cli.subcommand(
Command::new("listActivities").alias("lac"),
command_list_activities,
);
cli.subcommand(
Command::new("editActivities").alias("eac"),
command_edit_activities,
);
mize.register_part(Box::new(TimeTrack { mize: mize.clone() }));
Ok(())
}
impl MizePart for TimeTrack {
fn name(&self) -> &'static str {
"timetrack"
}
}
fn command_list_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
let activities = get_activities(&mut mize, spacetime.con())?;
for ac in activities.clone() {
print!("ac {}: {}", ac.id, ac.name);
if !ac.parents_ids.is_empty() {
print!(" -");
}
for child_id in ac.parents_ids {
let child_ac = activities.iter().find(|ac| ac.id == child_id).unwrap();
print!(" {}", child_ac.name);
}
print!("\n")
}
Ok(())
}
fn command_edit_activities(_: &ArgMatches, mut mize: Mize) -> MizeResult<()> {
let mut spacetime = mize.get_part_native::<SpacetimePart>("spacetime")?;
// get list of activities
let activities = get_activities(&mut mize, spacetime.con())?;
let con = spacetime.con();
// write to tmp file
let mut tmp_file_content = String::new();
for ac in activities.iter() {
tmp_file_content.push_str(format!("{} {}", ac.id, ac.name).as_str());
if !ac.parents_ids.is_empty() {
tmp_file_content.push_str(" -");
for parent_id in ac.parents_ids.iter() {
let parent_ac = activities.iter().find(|ac| ac.id == *parent_id).unwrap();
tmp_file_content.push_str(" ");
tmp_file_content.push_str(&parent_ac.name);
}
}
tmp_file_content.push_str("\n");
}
let tmp_file = std::env::temp_dir().join(format!(
"ppc-edit-activities-{}.txt",
chrono::Utc::now().timestamp()
));
std::fs::write(&tmp_file, tmp_file_content)
.map_err(|e| mize_err!("Failed to write temp file: {}", e))?;
loop {
// open $EDITOR blocking
std::process::Command::new("nvim")
.arg(&tmp_file)
.status()
.map_err(|e| mize_err!("Failed to run nvim: {}", e))?;
let new_file_content = std::fs::read_to_string(&tmp_file)
.map_err(|e| mize_err!("Failed to read temp file: {}", e))?;
let mut input = String::new();
let old_activities = get_activities(&mut mize, con)?;
if let Err(err) =
parse_activities_from_text(&mut mize, con, new_file_content, old_activities)
{
println!("error parsing the activities from the file: {:?}", err);
println!("press ENTER to open the file again");
// wait for user input
// so that they can se the err msg, before running nvim again
std::io::stdin().read_line(&mut input)?;
} else {
break;
}
}
// delete tmpfile
let _ = std::fs::remove_file(&tmp_file);
Ok(())
}
fn get_activities(mize: &mut Mize, con: &mut DbConnection) -> MizeResult<Vec<Activity>> {
let (exit_tx, exit_rx) = std::sync::oneshot::channel::<Vec<Activity>>();
con.subscription_builder()
.on_applied(|ctx| {
exit_tx.send(ctx.db.activities().iter().collect()).unwrap();
})
.add_query(|q| q.from.activities())
.subscribe();
let activities = exit_rx.recv().unwrap();
Ok(activities)
}
fn parse_activities_from_text(
mize: &mut Mize,
con: &mut DbConnection,
text: String,
old_activities: Vec<Activity>,
) -> MizeResult<()> {
let mut activities_to_delete = old_activities.clone();
let mut wait_revievers = Vec::new();
for line in text.lines() {
if line == "" {
continue;
}
// split
let mut parts = line.split(" ");
let id: u64 = parts.next().ok_or(mize_err!(".."))?.parse()?;
let name = parts.next().ok_or(mize_err!(".."))?.to_string();
// remove from to-delete list
if let Some(pos) = activities_to_delete.iter().position(|ac| ac.id == id) {
activities_to_delete.remove(pos);
}
// wait rx
let (wait_tx, wait_rx) = oneshot::channel::<()>();
wait_revievers.push(wait_rx);
// update or create activity
if let Some(old_activity) = old_activities.iter().find(|ac| ac.id == id) {
con.reducers.update_activity_then(
Activity {
id,
name,
task: old_activity.task,
parents_ids: old_activity.parents_ids.clone(),
},
move |_, _| {
wait_tx.send(());
},
)?;
} else {
con.reducers.update_activity_then(
Activity {
id: 0,
name,
task: None,
parents_ids: Vec::new(),
},
move |_, _| {
wait_tx.send(());
},
)?;
}
}
// remove deleted activities
for activity in activities_to_delete {
let (wait_tx, wait_rx) = oneshot::channel::<()>();
wait_revievers.push(wait_rx);
con.reducers.remove_activity_then(activity, move |_, _| {
wait_tx.send(());
})?;
}
// wait for db stuff to finish
for wait_rx in wait_revievers {
wait_rx.recv().unwrap();
}
let mut wait_revievers = Vec::new();
// check for declared parents
let new_activities = get_activities(mize, con)?;
println!("new_activities: {:?}", new_activities);
for line in text.lines() {
if line == "" {
continue;
}
// split
let mut parts = line.split(" ");
let id: u64 = parts.next().ok_or(mize_err!(".."))?.parse()?;
let name = parts.next().ok_or(mize_err!(".."))?.to_string();
// parse parents
let seperator = parts.next();
if seperator.is_some() && seperator.unwrap() == "-" {
let mut parents_ids = Vec::new();
for parent_name in parts {
// find id from old_parts by this name
let res_from_old = old_activities.iter().find(|ac| ac.name == parent_name);
let res_from_new = new_activities.iter().find(|ac| ac.name == parent_name);
let parent_activity = res_from_old.or(res_from_new).ok_or(mize_err!(
"activity '{name}' declares parent '{parent_name}'"
))?;
parents_ids.push(parent_activity.id);
}
let child_activity = new_activities
.iter()
.find(|ac| ac.name == name)
.ok_or(mize_err!(".."))?;
let (wait_tx, wait_rx) = oneshot::channel::<()>();
wait_revievers.push(wait_rx);
con.reducers.update_activity_then(
Activity {
parents_ids,
..child_activity.to_owned()
},
move |_, _| {
wait_tx.send(());
},
);
}
}
// wait for db stuff to finish
for wait_rx in wait_revievers {
wait_rx.recv().unwrap();
}
Ok(())
}

View File

@@ -1,104 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub(super) struct AddArgs {
pub username: String,
}
impl From<AddArgs> for super::Reducer {
fn from(args: AddArgs) -> Self {
Self::Add {
username: args.username,
}
}
}
impl __sdk::InModule for AddArgs {
type Module = super::RemoteModule;
}
pub struct AddCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `add`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait add {
/// Request that the remote module invoke the reducer `add` to run as soon as possible.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and its status can be observed by listening for [`Self::on_add`] callbacks.
fn add(&self, username: String) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `add`.
///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status.
///
/// The returned [`AddCallbackId`] can be passed to [`Self::remove_on_add`]
/// to cancel the callback.
fn on_add(
&self,
callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static,
) -> AddCallbackId;
/// Cancel a callback previously registered by [`Self::on_add`],
/// causing it not to run in the future.
fn remove_on_add(&self, callback: AddCallbackId);
}
impl add for super::RemoteReducers {
fn add(&self, username: String) -> __sdk::Result<()> {
self.imp.call_reducer("add", AddArgs { username })
}
fn on_add(
&self,
mut callback: impl FnMut(&super::ReducerEventContext, &String) + Send + 'static,
) -> AddCallbackId {
AddCallbackId(self.imp.on_reducer(
"add",
Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)]
let super::ReducerEventContext {
event:
__sdk::ReducerEvent {
reducer: super::Reducer::Add { username },
..
},
..
} = ctx
else {
unreachable!()
};
callback(ctx, username)
}),
))
}
fn remove_on_add(&self, callback: AddCallbackId) {
self.imp.remove_on_reducer("add", callback.0)
}
}
#[allow(non_camel_case_types)]
#[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `add`.
///
/// Implemented for [`super::SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_add {
/// Set the call-reducer flags for the reducer `add` to `flags`.
///
/// This type is currently unstable and may be removed without a major version bump.
fn add(&self, flags: __ws::CallReducerFlags);
}
impl set_flags_for_add for super::SetReducerFlags {
fn add(&self, flags: __ws::CallReducerFlags) {
self.imp.set_call_reducer_flags("add", flags);
}
}

View File

@@ -1,101 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub(super) struct IdentityConnectedArgs {}
impl From<IdentityConnectedArgs> for super::Reducer {
fn from(args: IdentityConnectedArgs) -> Self {
Self::IdentityConnected
}
}
impl __sdk::InModule for IdentityConnectedArgs {
type Module = super::RemoteModule;
}
pub struct IdentityConnectedCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `identity_connected`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait identity_connected {
/// Request that the remote module invoke the reducer `identity_connected` to run as soon as possible.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and its status can be observed by listening for [`Self::on_identity_connected`] callbacks.
fn identity_connected(&self) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `identity_connected`.
///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status.
///
/// The returned [`IdentityConnectedCallbackId`] can be passed to [`Self::remove_on_identity_connected`]
/// to cancel the callback.
fn on_identity_connected(
&self,
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> IdentityConnectedCallbackId;
/// Cancel a callback previously registered by [`Self::on_identity_connected`],
/// causing it not to run in the future.
fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId);
}
impl identity_connected for super::RemoteReducers {
fn identity_connected(&self) -> __sdk::Result<()> {
self.imp
.call_reducer("identity_connected", IdentityConnectedArgs {})
}
fn on_identity_connected(
&self,
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> IdentityConnectedCallbackId {
IdentityConnectedCallbackId(self.imp.on_reducer(
"identity_connected",
Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)]
let super::ReducerEventContext {
event:
__sdk::ReducerEvent {
reducer: super::Reducer::IdentityConnected {},
..
},
..
} = ctx
else {
unreachable!()
};
callback(ctx)
}),
))
}
fn remove_on_identity_connected(&self, callback: IdentityConnectedCallbackId) {
self.imp.remove_on_reducer("identity_connected", callback.0)
}
}
#[allow(non_camel_case_types)]
#[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `identity_connected`.
///
/// Implemented for [`super::SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_identity_connected {
/// Set the call-reducer flags for the reducer `identity_connected` to `flags`.
///
/// This type is currently unstable and may be removed without a major version bump.
fn identity_connected(&self, flags: __ws::CallReducerFlags);
}
impl set_flags_for_identity_connected for super::SetReducerFlags {
fn identity_connected(&self, flags: __ws::CallReducerFlags) {
self.imp.set_call_reducer_flags("identity_connected", flags);
}
}

View File

@@ -1,103 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub(super) struct IdentityDisconnectedArgs {}
impl From<IdentityDisconnectedArgs> for super::Reducer {
fn from(args: IdentityDisconnectedArgs) -> Self {
Self::IdentityDisconnected
}
}
impl __sdk::InModule for IdentityDisconnectedArgs {
type Module = super::RemoteModule;
}
pub struct IdentityDisconnectedCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `identity_disconnected`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait identity_disconnected {
/// Request that the remote module invoke the reducer `identity_disconnected` to run as soon as possible.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and its status can be observed by listening for [`Self::on_identity_disconnected`] callbacks.
fn identity_disconnected(&self) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `identity_disconnected`.
///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status.
///
/// The returned [`IdentityDisconnectedCallbackId`] can be passed to [`Self::remove_on_identity_disconnected`]
/// to cancel the callback.
fn on_identity_disconnected(
&self,
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> IdentityDisconnectedCallbackId;
/// Cancel a callback previously registered by [`Self::on_identity_disconnected`],
/// causing it not to run in the future.
fn remove_on_identity_disconnected(&self, callback: IdentityDisconnectedCallbackId);
}
impl identity_disconnected for super::RemoteReducers {
fn identity_disconnected(&self) -> __sdk::Result<()> {
self.imp
.call_reducer("identity_disconnected", IdentityDisconnectedArgs {})
}
fn on_identity_disconnected(
&self,
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> IdentityDisconnectedCallbackId {
IdentityDisconnectedCallbackId(self.imp.on_reducer(
"identity_disconnected",
Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)]
let super::ReducerEventContext {
event:
__sdk::ReducerEvent {
reducer: super::Reducer::IdentityDisconnected {},
..
},
..
} = ctx
else {
unreachable!()
};
callback(ctx)
}),
))
}
fn remove_on_identity_disconnected(&self, callback: IdentityDisconnectedCallbackId) {
self.imp
.remove_on_reducer("identity_disconnected", callback.0)
}
}
#[allow(non_camel_case_types)]
#[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `identity_disconnected`.
///
/// Implemented for [`super::SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_identity_disconnected {
/// Set the call-reducer flags for the reducer `identity_disconnected` to `flags`.
///
/// This type is currently unstable and may be removed without a major version bump.
fn identity_disconnected(&self, flags: __ws::CallReducerFlags);
}
impl set_flags_for_identity_disconnected for super::SetReducerFlags {
fn identity_disconnected(&self, flags: __ws::CallReducerFlags) {
self.imp
.set_call_reducer_flags("identity_disconnected", flags);
}
}

View File

@@ -1,95 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use super::person_type::Person;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// Table handle for the table `person`.
///
/// Obtain a handle from the [`PersonTableAccess::person`] method on [`super::RemoteTables`],
/// like `ctx.db.person()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.person().on_insert(...)`.
pub struct PersonTableHandle<'ctx> {
imp: __sdk::TableHandle<Person>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `person`.
///
/// Implemented for [`super::RemoteTables`].
pub trait PersonTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`PersonTableHandle`], which mediates access to the table `person`.
fn person(&self) -> PersonTableHandle<'_>;
}
impl PersonTableAccess for super::RemoteTables {
fn person(&self) -> PersonTableHandle<'_> {
PersonTableHandle {
imp: self.imp.get_table::<Person>("person"),
ctx: std::marker::PhantomData,
}
}
}
pub struct PersonInsertCallbackId(__sdk::CallbackId);
pub struct PersonDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for PersonTableHandle<'ctx> {
type Row = Person;
type EventContext = super::EventContext;
fn count(&self) -> u64 {
self.imp.count()
}
fn iter(&self) -> impl Iterator<Item = Person> + '_ {
self.imp.iter()
}
type InsertCallbackId = PersonInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> PersonInsertCallbackId {
PersonInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: PersonInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = PersonDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> PersonDeleteCallbackId {
PersonDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: PersonDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
#[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<Person>("person");
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::TableUpdate<__ws::BsatnFormat>,
) -> __sdk::Result<__sdk::TableUpdate<Person>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<Person>", "TableUpdate")
.with_cause(e)
.into()
})
}

View File

@@ -1,15 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct Person {
pub username: String,
}
impl __sdk::InModule for Person {
type Module = super::RemoteModule;
}

View File

@@ -1,100 +0,0 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub(super) struct SayHelloArgs {}
impl From<SayHelloArgs> for super::Reducer {
fn from(args: SayHelloArgs) -> Self {
Self::SayHello
}
}
impl __sdk::InModule for SayHelloArgs {
type Module = super::RemoteModule;
}
pub struct SayHelloCallbackId(__sdk::CallbackId);
#[allow(non_camel_case_types)]
/// Extension trait for access to the reducer `say_hello`.
///
/// Implemented for [`super::RemoteReducers`].
pub trait say_hello {
/// Request that the remote module invoke the reducer `say_hello` to run as soon as possible.
///
/// This method returns immediately, and errors only if we are unable to send the request.
/// The reducer will run asynchronously in the future,
/// and its status can be observed by listening for [`Self::on_say_hello`] callbacks.
fn say_hello(&self) -> __sdk::Result<()>;
/// Register a callback to run whenever we are notified of an invocation of the reducer `say_hello`.
///
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
/// to determine the reducer's status.
///
/// The returned [`SayHelloCallbackId`] can be passed to [`Self::remove_on_say_hello`]
/// to cancel the callback.
fn on_say_hello(
&self,
callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> SayHelloCallbackId;
/// Cancel a callback previously registered by [`Self::on_say_hello`],
/// causing it not to run in the future.
fn remove_on_say_hello(&self, callback: SayHelloCallbackId);
}
impl say_hello for super::RemoteReducers {
fn say_hello(&self) -> __sdk::Result<()> {
self.imp.call_reducer("say_hello", SayHelloArgs {})
}
fn on_say_hello(
&self,
mut callback: impl FnMut(&super::ReducerEventContext) + Send + 'static,
) -> SayHelloCallbackId {
SayHelloCallbackId(self.imp.on_reducer(
"say_hello",
Box::new(move |ctx: &super::ReducerEventContext| {
#[allow(irrefutable_let_patterns)]
let super::ReducerEventContext {
event:
__sdk::ReducerEvent {
reducer: super::Reducer::SayHello {},
..
},
..
} = ctx
else {
unreachable!()
};
callback(ctx)
}),
))
}
fn remove_on_say_hello(&self, callback: SayHelloCallbackId) {
self.imp.remove_on_reducer("say_hello", callback.0)
}
}
#[allow(non_camel_case_types)]
#[doc(hidden)]
/// Extension trait for setting the call-flags for the reducer `say_hello`.
///
/// Implemented for [`super::SetReducerFlags`].
///
/// This type is currently unstable and may be removed without a major version bump.
pub trait set_flags_for_say_hello {
/// Set the call-reducer flags for the reducer `say_hello` to `flags`.
///
/// This type is currently unstable and may be removed without a major version bump.
fn say_hello(&self, flags: __ws::CallReducerFlags);
}
impl set_flags_for_say_hello for super::SetReducerFlags {
fn say_hello(&self, flags: __ws::CallReducerFlags) {
self.imp.set_call_reducer_flags("say_hello", flags);
}
}