持久化认证状态到 SpacetimeDB 正式表

This commit is contained in:
2026-04-24 16:09:20 +08:00
parent 04288d4a40
commit 4e1c0462a4
29 changed files with 2271 additions and 7341 deletions

View File

@@ -217,6 +217,8 @@ impl AppState {
self.spacetime_client
.upsert_auth_store_snapshot(snapshot_json, updated_at_micros)
.await?;
// ?????????????????????????????????
self.spacetime_client.import_auth_store_snapshot().await?;
Ok(())
}
@@ -229,19 +231,38 @@ impl AppState {
token: config.spacetime_token.clone(),
pool_size: config.spacetime_pool_size,
});
match spacetime_client
.export_auth_store_snapshot_from_tables()
.await
{
Ok(snapshot) => {
if let Some(snapshot_json) = snapshot.snapshot_json {
if !snapshot_json.trim().is_empty() {
let auth_store = InMemoryAuthStore::from_snapshot_json(&snapshot_json)
.map_err(AppStateInitError::AuthStore)?;
info!("?? SpacetimeDB ???????????");
return Self::new_with_auth_store(config, auth_store);
}
}
}
Err(error) => {
warn!(error = %error, "? SpacetimeDB ????????????????");
}
}
match spacetime_client.get_auth_store_snapshot().await {
Ok(snapshot) => {
if let Some(snapshot_json) = snapshot.snapshot_json {
if !snapshot_json.trim().is_empty() {
let auth_store = InMemoryAuthStore::from_snapshot_json(&snapshot_json)
.map_err(AppStateInitError::AuthStore)?;
info!("已从 SpacetimeDB 恢复认证快照");
info!("?? SpacetimeDB ???????????");
return Self::new_with_auth_store(config, auth_store);
}
}
}
Err(error) => {
warn!(error = %error, " SpacetimeDB 恢复认证快照失败,回退到本地快照");
warn!(error = %error, "? SpacetimeDB ?????????????????");
}
}

View File

@@ -1,11 +1,12 @@
use super::*;
use crate::mapper::*;
impl SpacetimeClient {
pub async fn create_ai_task(
&self,
input: DomainAiTaskCreateInput,
) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = map_ai_task_create_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().create_ai_task_and_return_then(
@@ -21,12 +22,11 @@ impl SpacetimeClient {
.await
}
pub async fn start_ai_task(
&self,
input: DomainAiTaskStartInput,
) -> Result<(), SpacetimeClientError> {
let reducer_input = map_ai_task_start_input(input);
let reducer_input = input.into();
self.call_reducer_after_connect(move |connection, sender| {
let callback_sender = sender.clone();
@@ -49,12 +49,11 @@ impl SpacetimeClient {
.await
}
pub async fn start_ai_task_stage(
&self,
input: DomainAiTaskStageStartInput,
) -> Result<(), SpacetimeClientError> {
let reducer_input = map_ai_task_stage_start_input(input);
let reducer_input = input.into();
self.call_reducer_after_connect(move |connection, sender| {
let callback_sender = sender.clone();
@@ -77,12 +76,11 @@ impl SpacetimeClient {
.await
}
pub async fn append_ai_text_chunk(
&self,
input: DomainAiTextChunkAppendInput,
) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = map_ai_text_chunk_append_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -97,12 +95,11 @@ impl SpacetimeClient {
.await
}
pub async fn complete_ai_stage(
&self,
input: DomainAiStageCompletionInput,
) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = map_ai_stage_completion_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().complete_ai_stage_and_return_then(
@@ -118,12 +115,11 @@ impl SpacetimeClient {
.await
}
pub async fn attach_ai_result_reference(
&self,
input: DomainAiResultReferenceInput,
) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = map_ai_result_reference_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -138,12 +134,11 @@ impl SpacetimeClient {
.await
}
pub async fn complete_ai_task(
&self,
input: DomainAiTaskFinishInput,
) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = map_ai_task_finish_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().complete_ai_task_and_return_then(
@@ -159,12 +154,11 @@ impl SpacetimeClient {
.await
}
pub async fn fail_ai_task(
&self,
input: DomainAiTaskFailureInput,
) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = map_ai_task_failure_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().fail_ai_task_and_return_then(
@@ -180,12 +174,11 @@ impl SpacetimeClient {
.await
}
pub async fn cancel_ai_task(
&self,
input: DomainAiTaskCancelInput,
) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = map_ai_task_cancel_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().cancel_ai_task_and_return_then(
@@ -200,6 +193,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -5,7 +5,7 @@ impl SpacetimeClient {
&self,
input: module_assets::AssetObjectUpsertInput,
) -> Result<AssetObjectRecord, SpacetimeClientError> {
let procedure_input = map_upsert_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -20,12 +20,11 @@ impl SpacetimeClient {
.await
}
pub async fn bind_asset_object_to_entity(
&self,
input: module_assets::AssetEntityBindingInput,
) -> Result<AssetEntityBindingRecord, SpacetimeClientError> {
let procedure_input = map_entity_binding_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -39,6 +38,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -1,6 +1,22 @@
use super::*;
impl SpacetimeClient {
pub async fn export_auth_store_snapshot_from_tables(
&self,
) -> Result<AuthStoreSnapshotRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| {
connection
.procedures()
.export_auth_store_snapshot_from_tables_then(move |_, result| {
let mapped = result
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
.and_then(map_auth_store_snapshot_procedure_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn get_auth_store_snapshot(
&self,
) -> Result<AuthStoreSnapshotRecord, SpacetimeClientError> {
@@ -17,7 +33,6 @@ impl SpacetimeClient {
.await
}
pub async fn upsert_auth_store_snapshot(
&self,
snapshot_json: String,
@@ -42,5 +57,19 @@ impl SpacetimeClient {
.await
}
pub async fn import_auth_store_snapshot(
&self,
) -> Result<AuthStoreSnapshotImportRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| {
connection
.procedures()
.import_auth_store_snapshot_then(move |_, result| {
let mapped = result
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
.and_then(map_auth_store_snapshot_import_procedure_result);
send_once(&sender, mapped);
});
})
.await
}
}

View File

@@ -1,4 +1,5 @@
use super::*;
use crate::mapper::*;
impl SpacetimeClient {
pub async fn create_big_fish_session(
@@ -28,7 +29,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_big_fish_session(
&self,
session_id: String,
@@ -52,7 +52,6 @@ impl SpacetimeClient {
.await
}
pub async fn list_big_fish_works(
&self,
owner_user_id: String,
@@ -72,7 +71,6 @@ impl SpacetimeClient {
.await
}
pub async fn submit_big_fish_message(
&self,
input: BigFishMessageSubmitRecordInput,
@@ -100,6 +98,34 @@ impl SpacetimeClient {
.await
}
pub async fn finalize_big_fish_agent_message(
&self,
input: BigFishMessageFinalizeRecordInput,
) -> Result<BigFishSessionRecord, SpacetimeClientError> {
let procedure_input = BigFishMessageFinalizeInput {
session_id: input.session_id,
owner_user_id: input.owner_user_id,
assistant_message_id: input.assistant_message_id,
assistant_reply_text: input.assistant_reply_text,
stage: parse_big_fish_creation_stage(&input.stage)?,
progress_percent: input.progress_percent,
anchor_pack_json: input.anchor_pack_json,
error_message: input.error_message,
updated_at_micros: input.updated_at_micros,
};
self.call_after_connect(move |connection, sender| {
connection
.procedures()
.finalize_big_fish_agent_message_turn_then(procedure_input, move |_, result| {
let mapped = result
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
.and_then(map_big_fish_session_procedure_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn compile_big_fish_draft(
&self,
@@ -127,7 +153,6 @@ impl SpacetimeClient {
.await
}
pub async fn generate_big_fish_asset(
&self,
input: BigFishAssetGenerateRecordInput,
@@ -135,7 +160,7 @@ impl SpacetimeClient {
let procedure_input = BigFishAssetGenerateInput {
session_id: input.session_id,
owner_user_id: input.owner_user_id,
asset_kind: map_big_fish_asset_kind_input(input.asset_kind.as_str())?,
asset_kind: input.asset_kind.as_str().try_into()?,
level: input.level,
motion_key: input.motion_key,
asset_url: input.asset_url,
@@ -156,7 +181,6 @@ impl SpacetimeClient {
.await
}
pub async fn publish_big_fish_game(
&self,
session_id: String,
@@ -183,7 +207,6 @@ impl SpacetimeClient {
.await
}
pub async fn start_big_fish_run(
&self,
input: BigFishRunStartRecordInput,
@@ -208,7 +231,6 @@ impl SpacetimeClient {
.await
}
pub async fn submit_big_fish_input(
&self,
input: BigFishRunInputSubmitRecordInput,
@@ -235,7 +257,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_big_fish_run(
&self,
run_id: String,
@@ -258,6 +279,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -1,4 +1,5 @@
use super::*;
use crate::mapper::*;
impl SpacetimeClient {
pub async fn create_battle_state(
@@ -7,7 +8,7 @@ impl SpacetimeClient {
) -> Result<BattleStateRecord, SpacetimeClientError> {
validate_battle_state_input(&input)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?;
let procedure_input = map_battle_state_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().create_battle_state_and_return_then(
@@ -23,15 +24,13 @@ impl SpacetimeClient {
.await
}
pub async fn get_battle_state(
&self,
battle_state_id: String,
) -> Result<BattleStateRecord, SpacetimeClientError> {
let procedure_input = map_battle_state_query_input(
build_battle_state_query_input(battle_state_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_battle_state_query_input(battle_state_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -46,14 +45,13 @@ impl SpacetimeClient {
.await
}
pub async fn resolve_combat_action(
&self,
input: DomainResolveCombatActionInput,
) -> Result<ResolveCombatActionRecord, SpacetimeClientError> {
validate_resolve_combat_action_input(&input)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?;
let procedure_input = map_resolve_combat_action_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -67,6 +65,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -1,4 +1,5 @@
use super::*;
use crate::mapper::*;
impl SpacetimeClient {
pub async fn list_custom_world_profiles(
@@ -21,7 +22,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_custom_world_library_detail(
&self,
owner_user_id: String,
@@ -45,12 +45,11 @@ impl SpacetimeClient {
.await
}
pub async fn upsert_custom_world_profile(
&self,
input: CustomWorldProfileUpsertRecordInput,
) -> Result<CustomWorldLibraryMutationRecord, SpacetimeClientError> {
let procedure_input = map_custom_world_profile_upsert_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -65,7 +64,6 @@ impl SpacetimeClient {
.await
}
pub async fn publish_custom_world_profile(
&self,
profile_id: String,
@@ -97,7 +95,6 @@ impl SpacetimeClient {
.await
}
pub async fn unpublish_custom_world_profile(
&self,
profile_id: String,
@@ -128,7 +125,6 @@ impl SpacetimeClient {
.await
}
pub async fn delete_custom_world_profile(
&self,
profile_id: String,
@@ -154,7 +150,6 @@ impl SpacetimeClient {
.await
}
pub async fn list_custom_world_gallery_entries(
&self,
) -> Result<Vec<CustomWorldGalleryEntryRecord>, SpacetimeClientError> {
@@ -171,7 +166,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_custom_world_gallery_detail(
&self,
owner_user_id: String,
@@ -195,7 +189,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_custom_world_gallery_detail_by_code(
&self,
public_work_code: String,
@@ -215,12 +208,11 @@ impl SpacetimeClient {
.await
}
pub async fn publish_custom_world_world(
&self,
input: CustomWorldPublishWorldRecordInput,
) -> Result<CustomWorldPublishWorldRecord, SpacetimeClientError> {
let procedure_input = map_custom_world_publish_world_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().publish_custom_world_world_then(
@@ -236,7 +228,6 @@ impl SpacetimeClient {
.await
}
pub async fn create_custom_world_agent_session(
&self,
input: CustomWorldAgentSessionCreateRecordInput,
@@ -275,7 +266,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_custom_world_agent_session(
&self,
session_id: String,
@@ -300,7 +290,6 @@ impl SpacetimeClient {
.await
}
pub async fn list_custom_world_works(
&self,
owner_user_id: String,
@@ -321,7 +310,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_custom_world_agent_card_detail(
&self,
session_id: String,
@@ -347,7 +335,6 @@ impl SpacetimeClient {
.await
}
pub async fn execute_custom_world_agent_action(
&self,
input: CustomWorldAgentActionExecuteRecordInput,
@@ -374,7 +361,6 @@ impl SpacetimeClient {
.await
}
pub async fn submit_custom_world_agent_message(
&self,
input: CustomWorldAgentMessageSubmitRecordInput,
@@ -401,7 +387,6 @@ impl SpacetimeClient {
.await
}
pub async fn finalize_custom_world_agent_message(
&self,
input: CustomWorldAgentMessageFinalizeRecordInput,
@@ -451,7 +436,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_custom_world_agent_operation(
&self,
session_id: String,
@@ -476,6 +460,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -6,10 +6,10 @@ impl SpacetimeClient {
runtime_session_id: String,
actor_user_id: String,
) -> Result<RuntimeInventoryStateRecord, SpacetimeClientError> {
let procedure_input = map_runtime_inventory_state_query_input(
let procedure_input =
build_runtime_inventory_state_query_input(runtime_session_id, actor_user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().get_runtime_inventory_state_then(
@@ -24,6 +24,4 @@ impl SpacetimeClient {
})
.await
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,163 @@
// 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::auth_identity_type::AuthIdentity;
/// Table handle for the table `auth_identity`.
///
/// Obtain a handle from the [`AuthIdentityTableAccess::auth_identity`] method on [`super::RemoteTables`],
/// like `ctx.db.auth_identity()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.auth_identity().on_insert(...)`.
pub struct AuthIdentityTableHandle<'ctx> {
imp: __sdk::TableHandle<AuthIdentity>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `auth_identity`.
///
/// Implemented for [`super::RemoteTables`].
pub trait AuthIdentityTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`AuthIdentityTableHandle`], which mediates access to the table `auth_identity`.
fn auth_identity(&self) -> AuthIdentityTableHandle<'_>;
}
impl AuthIdentityTableAccess for super::RemoteTables {
fn auth_identity(&self) -> AuthIdentityTableHandle<'_> {
AuthIdentityTableHandle {
imp: self.imp.get_table::<AuthIdentity>("auth_identity"),
ctx: std::marker::PhantomData,
}
}
}
pub struct AuthIdentityInsertCallbackId(__sdk::CallbackId);
pub struct AuthIdentityDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for AuthIdentityTableHandle<'ctx> {
type Row = AuthIdentity;
type EventContext = super::EventContext;
fn count(&self) -> u64 { self.imp.count() }
fn iter(&self) -> impl Iterator<Item = AuthIdentity> + '_ { self.imp.iter() }
type InsertCallbackId = AuthIdentityInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> AuthIdentityInsertCallbackId {
AuthIdentityInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: AuthIdentityInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = AuthIdentityDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> AuthIdentityDeleteCallbackId {
AuthIdentityDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: AuthIdentityDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct AuthIdentityUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for AuthIdentityTableHandle<'ctx> {
type UpdateCallbackId = AuthIdentityUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> AuthIdentityUpdateCallbackId {
AuthIdentityUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: AuthIdentityUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `identity_id` unique index on the table `auth_identity`,
/// which allows point queries on the field of the same name
/// via the [`AuthIdentityIdentityIdUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.auth_identity().identity_id().find(...)`.
pub struct AuthIdentityIdentityIdUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<AuthIdentity, String>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> AuthIdentityTableHandle<'ctx> {
/// Get a handle on the `identity_id` unique index on the table `auth_identity`.
pub fn identity_id(&self) -> AuthIdentityIdentityIdUnique<'ctx> {
AuthIdentityIdentityIdUnique {
imp: self.imp.get_unique_constraint::<String>("identity_id"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> AuthIdentityIdentityIdUnique<'ctx> {
/// Find the subscribed row whose `identity_id` 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<AuthIdentity> {
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::<AuthIdentity>("auth_identity");
_table.add_unique_constraint::<String>("identity_id", |row| &row.identity_id);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<AuthIdentity>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse(
"TableUpdate<AuthIdentity>",
"TableUpdate",
).with_cause(e).into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `AuthIdentity`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait auth_identityQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `AuthIdentity`.
fn auth_identity(&self) -> __sdk::__query_builder::Table<AuthIdentity>;
}
impl auth_identityQueryTableAccess for __sdk::QueryTableAccessor {
fn auth_identity(&self) -> __sdk::__query_builder::Table<AuthIdentity> {
__sdk::__query_builder::Table::new("auth_identity")
}
}

View File

@@ -0,0 +1,83 @@
// 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 AuthIdentity {
pub identity_id: String,
pub user_id: String,
pub provider: String,
pub provider_uid: String,
pub provider_union_id: Option::<String>,
pub phone_e_164: Option::<String>,
pub display_name: Option::<String>,
pub avatar_url: Option::<String>,
}
impl __sdk::InModule for AuthIdentity {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `AuthIdentity`.
///
/// Provides typed access to columns for query building.
pub struct AuthIdentityCols {
pub identity_id: __sdk::__query_builder::Col<AuthIdentity, String>,
pub user_id: __sdk::__query_builder::Col<AuthIdentity, String>,
pub provider: __sdk::__query_builder::Col<AuthIdentity, String>,
pub provider_uid: __sdk::__query_builder::Col<AuthIdentity, String>,
pub provider_union_id: __sdk::__query_builder::Col<AuthIdentity, Option::<String>>,
pub phone_e_164: __sdk::__query_builder::Col<AuthIdentity, Option::<String>>,
pub display_name: __sdk::__query_builder::Col<AuthIdentity, Option::<String>>,
pub avatar_url: __sdk::__query_builder::Col<AuthIdentity, Option::<String>>,
}
impl __sdk::__query_builder::HasCols for AuthIdentity {
type Cols = AuthIdentityCols;
fn cols(table_name: &'static str) -> Self::Cols {
AuthIdentityCols {
identity_id: __sdk::__query_builder::Col::new(table_name, "identity_id"),
user_id: __sdk::__query_builder::Col::new(table_name, "user_id"),
provider: __sdk::__query_builder::Col::new(table_name, "provider"),
provider_uid: __sdk::__query_builder::Col::new(table_name, "provider_uid"),
provider_union_id: __sdk::__query_builder::Col::new(table_name, "provider_union_id"),
phone_e_164: __sdk::__query_builder::Col::new(table_name, "phone_e_164"),
display_name: __sdk::__query_builder::Col::new(table_name, "display_name"),
avatar_url: __sdk::__query_builder::Col::new(table_name, "avatar_url"),
}
}
}
/// Indexed column accessor struct for the table `AuthIdentity`.
///
/// Provides typed access to indexed columns for query building.
pub struct AuthIdentityIxCols {
pub identity_id: __sdk::__query_builder::IxCol<AuthIdentity, String>,
pub user_id: __sdk::__query_builder::IxCol<AuthIdentity, String>,
}
impl __sdk::__query_builder::HasIxCols for AuthIdentity {
type IxCols = AuthIdentityIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
AuthIdentityIxCols {
identity_id: __sdk::__query_builder::IxCol::new(table_name, "identity_id"),
user_id: __sdk::__query_builder::IxCol::new(table_name, "user_id"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for AuthIdentity {}

View File

@@ -0,0 +1,26 @@
// 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::auth_store_snapshot_import_record_type::AuthStoreSnapshotImportRecord;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct AuthStoreSnapshotImportProcedureResult {
pub ok: bool,
pub record: Option::<AuthStoreSnapshotImportRecord>,
pub error_message: Option::<String>,
}
impl __sdk::InModule for AuthStoreSnapshotImportProcedureResult {
type Module = super::RemoteModule;
}

View File

@@ -0,0 +1,25 @@
// 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 AuthStoreSnapshotImportRecord {
pub imported_user_count: u32,
pub imported_identity_count: u32,
pub imported_refresh_session_count: u32,
}
impl __sdk::InModule for AuthStoreSnapshotImportRecord {
type Module = super::RemoteModule;
}

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::auth_store_snapshot_procedure_result_type::AuthStoreSnapshotProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct ExportAuthStoreSnapshotFromTablesArgs {
}
impl __sdk::InModule for ExportAuthStoreSnapshotFromTablesArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `export_auth_store_snapshot_from_tables`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait export_auth_store_snapshot_from_tables {
fn export_auth_store_snapshot_from_tables(&self, ) {
self.export_auth_store_snapshot_from_tables_then( |_, _| {});
}
fn export_auth_store_snapshot_from_tables_then(
&self,
__callback: impl FnOnce(&super::ProcedureEventContext, Result<AuthStoreSnapshotProcedureResult, __sdk::InternalError>) + Send + 'static,
);
}
impl export_auth_store_snapshot_from_tables for super::RemoteProcedures {
fn export_auth_store_snapshot_from_tables_then(
&self,
__callback: impl FnOnce(&super::ProcedureEventContext, Result<AuthStoreSnapshotProcedureResult, __sdk::InternalError>) + Send + 'static,
) {
self.imp.invoke_procedure_with_callback::<_, AuthStoreSnapshotProcedureResult>(
"export_auth_store_snapshot_from_tables",
ExportAuthStoreSnapshotFromTablesArgs { },
__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::auth_store_snapshot_import_procedure_result_type::AuthStoreSnapshotImportProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct ImportAuthStoreSnapshotArgs {
}
impl __sdk::InModule for ImportAuthStoreSnapshotArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `import_auth_store_snapshot`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait import_auth_store_snapshot {
fn import_auth_store_snapshot(&self, ) {
self.import_auth_store_snapshot_then( |_, _| {});
}
fn import_auth_store_snapshot_then(
&self,
__callback: impl FnOnce(&super::ProcedureEventContext, Result<AuthStoreSnapshotImportProcedureResult, __sdk::InternalError>) + Send + 'static,
);
}
impl import_auth_store_snapshot for super::RemoteProcedures {
fn import_auth_store_snapshot_then(
&self,
__callback: impl FnOnce(&super::ProcedureEventContext, Result<AuthStoreSnapshotImportProcedureResult, __sdk::InternalError>) + Send + 'static,
) {
self.imp.invoke_procedure_with_callback::<_, AuthStoreSnapshotImportProcedureResult>(
"import_auth_store_snapshot",
ImportAuthStoreSnapshotArgs { },
__callback,
);
}
}

View File

@@ -44,13 +44,13 @@ pub mod asset_object_access_policy_type;
pub mod asset_object_procedure_result_type;
pub mod asset_object_upsert_input_type;
pub mod asset_object_upsert_snapshot_type;
<<<<<<< HEAD
=======
pub mod auth_identity_type;
pub mod auth_store_snapshot_type;
pub mod auth_store_snapshot_import_procedure_result_type;
pub mod auth_store_snapshot_import_record_type;
pub mod auth_store_snapshot_procedure_result_type;
pub mod auth_store_snapshot_record_type;
pub mod auth_store_snapshot_upsert_input_type;
>>>>>>> 4f272a50 ( Spacetime )
pub mod battle_mode_type;
pub mod battle_state_type;
pub mod battle_state_input_type;
@@ -245,6 +245,7 @@ pub mod quest_status_type;
pub mod quest_step_snapshot_type;
pub mod quest_treasure_inspected_signal_type;
pub mod quest_turn_in_input_type;
pub mod refresh_session_type;
pub mod resolve_combat_action_input_type;
pub mod resolve_combat_action_procedure_result_type;
pub mod resolve_combat_action_result_type;
@@ -315,6 +316,7 @@ pub mod treasure_record_procedure_result_type;
pub mod treasure_record_snapshot_type;
pub mod treasure_resolve_input_type;
pub mod unequip_inventory_item_input_type;
pub mod user_account_type;
pub mod user_browse_history_type;
pub mod accept_quest_reducer;
pub mod acknowledge_quest_completion_reducer;
@@ -346,10 +348,8 @@ pub mod ai_task_stage_table;
pub mod ai_text_chunk_table;
pub mod asset_entity_binding_table;
pub mod asset_object_table;
<<<<<<< HEAD
=======
pub mod auth_identity_table;
pub mod auth_store_snapshot_table;
>>>>>>> 4f272a50 ( Spacetime )
pub mod battle_state_table;
pub mod big_fish_agent_message_table;
pub mod big_fish_asset_slot_table;
@@ -376,11 +376,13 @@ pub mod puzzle_runtime_run_table;
pub mod puzzle_work_profile_table;
pub mod quest_log_table;
pub mod quest_record_table;
pub mod refresh_session_table;
pub mod runtime_setting_table;
pub mod runtime_snapshot_table;
pub mod story_event_table;
pub mod story_session_table;
pub mod treasure_record_table;
pub mod user_account_table;
pub mod user_browse_history_table;
pub mod advance_puzzle_next_level_procedure;
pub mod append_ai_text_chunk_and_return_procedure;
@@ -406,18 +408,13 @@ pub mod delete_custom_world_profile_and_return_procedure;
pub mod delete_runtime_snapshot_and_return_procedure;
pub mod drag_puzzle_piece_or_group_procedure;
pub mod execute_custom_world_agent_action_procedure;
pub mod export_auth_store_snapshot_from_tables_procedure;
pub mod fail_ai_task_and_return_procedure;
<<<<<<< HEAD
pub mod finalize_big_fish_agent_message_turn_procedure;
pub mod finalize_custom_world_agent_message_turn_procedure;
pub mod finalize_puzzle_agent_message_turn_procedure;
pub mod generate_big_fish_asset_procedure;
=======
pub mod finalize_custom_world_agent_message_turn_procedure;
pub mod finalize_puzzle_agent_message_turn_procedure;
pub mod generate_big_fish_asset_procedure;
pub mod get_auth_store_snapshot_procedure;
>>>>>>> 4f272a50 ( Spacetime )
pub mod get_battle_state_procedure;
pub mod get_big_fish_run_procedure;
pub mod get_big_fish_session_procedure;
@@ -440,6 +437,7 @@ pub mod get_runtime_setting_or_default_procedure;
pub mod get_runtime_snapshot_procedure;
pub mod get_story_session_state_procedure;
pub mod grant_player_progression_experience_and_return_procedure;
pub mod import_auth_store_snapshot_procedure;
pub mod list_big_fish_works_procedure;
pub mod list_custom_world_gallery_entries_procedure;
pub mod list_custom_world_profiles_procedure;
@@ -511,13 +509,13 @@ pub use asset_object_access_policy_type::AssetObjectAccessPolicy;
pub use asset_object_procedure_result_type::AssetObjectProcedureResult;
pub use asset_object_upsert_input_type::AssetObjectUpsertInput;
pub use asset_object_upsert_snapshot_type::AssetObjectUpsertSnapshot;
<<<<<<< HEAD
=======
pub use auth_identity_type::AuthIdentity;
pub use auth_store_snapshot_type::AuthStoreSnapshot;
pub use auth_store_snapshot_import_procedure_result_type::AuthStoreSnapshotImportProcedureResult;
pub use auth_store_snapshot_import_record_type::AuthStoreSnapshotImportRecord;
pub use auth_store_snapshot_procedure_result_type::AuthStoreSnapshotProcedureResult;
pub use auth_store_snapshot_record_type::AuthStoreSnapshotRecord;
pub use auth_store_snapshot_upsert_input_type::AuthStoreSnapshotUpsertInput;
>>>>>>> 4f272a50 ( Spacetime )
pub use battle_mode_type::BattleMode;
pub use battle_state_type::BattleState;
pub use battle_state_input_type::BattleStateInput;
@@ -712,6 +710,7 @@ pub use quest_status_type::QuestStatus;
pub use quest_step_snapshot_type::QuestStepSnapshot;
pub use quest_treasure_inspected_signal_type::QuestTreasureInspectedSignal;
pub use quest_turn_in_input_type::QuestTurnInInput;
pub use refresh_session_type::RefreshSession;
pub use resolve_combat_action_input_type::ResolveCombatActionInput;
pub use resolve_combat_action_procedure_result_type::ResolveCombatActionProcedureResult;
pub use resolve_combat_action_result_type::ResolveCombatActionResult;
@@ -782,6 +781,7 @@ pub use treasure_record_procedure_result_type::TreasureRecordProcedureResult;
pub use treasure_record_snapshot_type::TreasureRecordSnapshot;
pub use treasure_resolve_input_type::TreasureResolveInput;
pub use unequip_inventory_item_input_type::UnequipInventoryItemInput;
pub use user_account_type::UserAccount;
pub use user_browse_history_type::UserBrowseHistory;
pub use ai_result_reference_table::*;
pub use ai_task_table::*;
@@ -789,10 +789,8 @@ pub use ai_task_stage_table::*;
pub use ai_text_chunk_table::*;
pub use asset_entity_binding_table::*;
pub use asset_object_table::*;
<<<<<<< HEAD
=======
pub use auth_identity_table::*;
pub use auth_store_snapshot_table::*;
>>>>>>> 4f272a50 ( Spacetime )
pub use battle_state_table::*;
pub use big_fish_agent_message_table::*;
pub use big_fish_asset_slot_table::*;
@@ -819,11 +817,13 @@ pub use puzzle_runtime_run_table::*;
pub use puzzle_work_profile_table::*;
pub use quest_log_table::*;
pub use quest_record_table::*;
pub use refresh_session_table::*;
pub use runtime_setting_table::*;
pub use runtime_snapshot_table::*;
pub use story_event_table::*;
pub use story_session_table::*;
pub use treasure_record_table::*;
pub use user_account_table::*;
pub use user_browse_history_table::*;
pub use accept_quest_reducer::accept_quest;
pub use acknowledge_quest_completion_reducer::acknowledge_quest_completion;
@@ -873,18 +873,13 @@ pub use delete_custom_world_profile_and_return_procedure::delete_custom_world_pr
pub use delete_runtime_snapshot_and_return_procedure::delete_runtime_snapshot_and_return;
pub use drag_puzzle_piece_or_group_procedure::drag_puzzle_piece_or_group;
pub use execute_custom_world_agent_action_procedure::execute_custom_world_agent_action;
pub use export_auth_store_snapshot_from_tables_procedure::export_auth_store_snapshot_from_tables;
pub use fail_ai_task_and_return_procedure::fail_ai_task_and_return;
<<<<<<< HEAD
pub use finalize_big_fish_agent_message_turn_procedure::finalize_big_fish_agent_message_turn;
pub use finalize_custom_world_agent_message_turn_procedure::finalize_custom_world_agent_message_turn;
pub use finalize_puzzle_agent_message_turn_procedure::finalize_puzzle_agent_message_turn;
pub use generate_big_fish_asset_procedure::generate_big_fish_asset;
=======
pub use finalize_custom_world_agent_message_turn_procedure::finalize_custom_world_agent_message_turn;
pub use finalize_puzzle_agent_message_turn_procedure::finalize_puzzle_agent_message_turn;
pub use generate_big_fish_asset_procedure::generate_big_fish_asset;
pub use get_auth_store_snapshot_procedure::get_auth_store_snapshot;
>>>>>>> 4f272a50 ( Spacetime )
pub use get_battle_state_procedure::get_battle_state;
pub use get_big_fish_run_procedure::get_big_fish_run;
pub use get_big_fish_session_procedure::get_big_fish_session;
@@ -907,6 +902,7 @@ pub use get_runtime_setting_or_default_procedure::get_runtime_setting_or_default
pub use get_runtime_snapshot_procedure::get_runtime_snapshot;
pub use get_story_session_state_procedure::get_story_session_state;
pub use grant_player_progression_experience_and_return_procedure::grant_player_progression_experience_and_return;
pub use import_auth_store_snapshot_procedure::import_auth_store_snapshot;
pub use list_big_fish_works_procedure::list_big_fish_works;
pub use list_custom_world_gallery_entries_procedure::list_custom_world_gallery_entries;
pub use list_custom_world_profiles_procedure::list_custom_world_profiles;
@@ -1200,6 +1196,7 @@ pub struct DbUpdate {
ai_text_chunk: __sdk::TableUpdate<AiTextChunk>,
asset_entity_binding: __sdk::TableUpdate<AssetEntityBinding>,
asset_object: __sdk::TableUpdate<AssetObject>,
auth_identity: __sdk::TableUpdate<AuthIdentity>,
auth_store_snapshot: __sdk::TableUpdate<AuthStoreSnapshot>,
battle_state: __sdk::TableUpdate<BattleState>,
big_fish_agent_message: __sdk::TableUpdate<BigFishAgentMessage>,
@@ -1227,11 +1224,13 @@ pub struct DbUpdate {
puzzle_work_profile: __sdk::TableUpdate<PuzzleWorkProfileRow>,
quest_log: __sdk::TableUpdate<QuestLog>,
quest_record: __sdk::TableUpdate<QuestRecord>,
refresh_session: __sdk::TableUpdate<RefreshSession>,
runtime_setting: __sdk::TableUpdate<RuntimeSetting>,
runtime_snapshot: __sdk::TableUpdate<RuntimeSnapshotRow>,
story_event: __sdk::TableUpdate<StoryEvent>,
story_session: __sdk::TableUpdate<StorySession>,
treasure_record: __sdk::TableUpdate<TreasureRecord>,
user_account: __sdk::TableUpdate<UserAccount>,
user_browse_history: __sdk::TableUpdate<UserBrowseHistory>,
}
@@ -1249,10 +1248,8 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
"ai_text_chunk" => db_update.ai_text_chunk.append(ai_text_chunk_table::parse_table_update(table_update)?),
"asset_entity_binding" => db_update.asset_entity_binding.append(asset_entity_binding_table::parse_table_update(table_update)?),
"asset_object" => db_update.asset_object.append(asset_object_table::parse_table_update(table_update)?),
<<<<<<< HEAD
=======
"auth_identity" => db_update.auth_identity.append(auth_identity_table::parse_table_update(table_update)?),
"auth_store_snapshot" => db_update.auth_store_snapshot.append(auth_store_snapshot_table::parse_table_update(table_update)?),
>>>>>>> 4f272a50 ( Spacetime )
"battle_state" => db_update.battle_state.append(battle_state_table::parse_table_update(table_update)?),
"big_fish_agent_message" => db_update.big_fish_agent_message.append(big_fish_agent_message_table::parse_table_update(table_update)?),
"big_fish_asset_slot" => db_update.big_fish_asset_slot.append(big_fish_asset_slot_table::parse_table_update(table_update)?),
@@ -1279,11 +1276,13 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
"puzzle_work_profile" => db_update.puzzle_work_profile.append(puzzle_work_profile_table::parse_table_update(table_update)?),
"quest_log" => db_update.quest_log.append(quest_log_table::parse_table_update(table_update)?),
"quest_record" => db_update.quest_record.append(quest_record_table::parse_table_update(table_update)?),
"refresh_session" => db_update.refresh_session.append(refresh_session_table::parse_table_update(table_update)?),
"runtime_setting" => db_update.runtime_setting.append(runtime_setting_table::parse_table_update(table_update)?),
"runtime_snapshot" => db_update.runtime_snapshot.append(runtime_snapshot_table::parse_table_update(table_update)?),
"story_event" => db_update.story_event.append(story_event_table::parse_table_update(table_update)?),
"story_session" => db_update.story_session.append(story_session_table::parse_table_update(table_update)?),
"treasure_record" => db_update.treasure_record.append(treasure_record_table::parse_table_update(table_update)?),
"user_account" => db_update.user_account.append(user_account_table::parse_table_update(table_update)?),
"user_browse_history" => db_update.user_browse_history.append(user_browse_history_table::parse_table_update(table_update)?),
unknown => {
@@ -1313,10 +1312,8 @@ impl __sdk::DbUpdate for DbUpdate {
diff.ai_text_chunk = cache.apply_diff_to_table::<AiTextChunk>("ai_text_chunk", &self.ai_text_chunk).with_updates_by_pk(|row| &row.text_chunk_row_id);
diff.asset_entity_binding = cache.apply_diff_to_table::<AssetEntityBinding>("asset_entity_binding", &self.asset_entity_binding).with_updates_by_pk(|row| &row.binding_id);
diff.asset_object = cache.apply_diff_to_table::<AssetObject>("asset_object", &self.asset_object).with_updates_by_pk(|row| &row.asset_object_id);
<<<<<<< HEAD
=======
diff.auth_identity = cache.apply_diff_to_table::<AuthIdentity>("auth_identity", &self.auth_identity).with_updates_by_pk(|row| &row.identity_id);
diff.auth_store_snapshot = cache.apply_diff_to_table::<AuthStoreSnapshot>("auth_store_snapshot", &self.auth_store_snapshot).with_updates_by_pk(|row| &row.snapshot_id);
>>>>>>> 4f272a50 ( Spacetime )
diff.battle_state = cache.apply_diff_to_table::<BattleState>("battle_state", &self.battle_state).with_updates_by_pk(|row| &row.battle_state_id);
diff.big_fish_agent_message = cache.apply_diff_to_table::<BigFishAgentMessage>("big_fish_agent_message", &self.big_fish_agent_message).with_updates_by_pk(|row| &row.message_id);
diff.big_fish_asset_slot = cache.apply_diff_to_table::<BigFishAssetSlot>("big_fish_asset_slot", &self.big_fish_asset_slot).with_updates_by_pk(|row| &row.slot_id);
@@ -1343,11 +1340,13 @@ impl __sdk::DbUpdate for DbUpdate {
diff.puzzle_work_profile = cache.apply_diff_to_table::<PuzzleWorkProfileRow>("puzzle_work_profile", &self.puzzle_work_profile).with_updates_by_pk(|row| &row.profile_id);
diff.quest_log = cache.apply_diff_to_table::<QuestLog>("quest_log", &self.quest_log).with_updates_by_pk(|row| &row.log_id);
diff.quest_record = cache.apply_diff_to_table::<QuestRecord>("quest_record", &self.quest_record).with_updates_by_pk(|row| &row.quest_id);
diff.refresh_session = cache.apply_diff_to_table::<RefreshSession>("refresh_session", &self.refresh_session).with_updates_by_pk(|row| &row.session_id);
diff.runtime_setting = cache.apply_diff_to_table::<RuntimeSetting>("runtime_setting", &self.runtime_setting).with_updates_by_pk(|row| &row.user_id);
diff.runtime_snapshot = cache.apply_diff_to_table::<RuntimeSnapshotRow>("runtime_snapshot", &self.runtime_snapshot).with_updates_by_pk(|row| &row.user_id);
diff.story_event = cache.apply_diff_to_table::<StoryEvent>("story_event", &self.story_event).with_updates_by_pk(|row| &row.event_id);
diff.story_session = cache.apply_diff_to_table::<StorySession>("story_session", &self.story_session).with_updates_by_pk(|row| &row.story_session_id);
diff.treasure_record = cache.apply_diff_to_table::<TreasureRecord>("treasure_record", &self.treasure_record).with_updates_by_pk(|row| &row.treasure_record_id);
diff.user_account = cache.apply_diff_to_table::<UserAccount>("user_account", &self.user_account).with_updates_by_pk(|row| &row.user_id);
diff.user_browse_history = cache.apply_diff_to_table::<UserBrowseHistory>("user_browse_history", &self.user_browse_history).with_updates_by_pk(|row| &row.browse_history_id);
diff
@@ -1362,10 +1361,8 @@ for table_rows in raw.tables {
"ai_text_chunk" => db_update.ai_text_chunk.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"asset_entity_binding" => db_update.asset_entity_binding.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"asset_object" => db_update.asset_object.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
<<<<<<< HEAD
=======
"auth_identity" => db_update.auth_identity.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"auth_store_snapshot" => db_update.auth_store_snapshot.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
>>>>>>> 4f272a50 ( Spacetime )
"battle_state" => db_update.battle_state.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"big_fish_agent_message" => db_update.big_fish_agent_message.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"big_fish_asset_slot" => db_update.big_fish_asset_slot.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
@@ -1392,11 +1389,13 @@ for table_rows in raw.tables {
"puzzle_work_profile" => db_update.puzzle_work_profile.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"quest_log" => db_update.quest_log.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"quest_record" => db_update.quest_record.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"refresh_session" => db_update.refresh_session.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"runtime_setting" => db_update.runtime_setting.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"runtime_snapshot" => db_update.runtime_snapshot.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"story_event" => db_update.story_event.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"story_session" => db_update.story_session.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"treasure_record" => db_update.treasure_record.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"user_account" => db_update.user_account.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
"user_browse_history" => db_update.user_browse_history.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
unknown => { return Err(__sdk::InternalError::unknown_name("table", unknown, "QueryRows").into()); }
}} Ok(db_update)
@@ -1411,10 +1410,8 @@ for table_rows in raw.tables {
"ai_text_chunk" => db_update.ai_text_chunk.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"asset_entity_binding" => db_update.asset_entity_binding.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"asset_object" => db_update.asset_object.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
<<<<<<< HEAD
=======
"auth_identity" => db_update.auth_identity.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"auth_store_snapshot" => db_update.auth_store_snapshot.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
>>>>>>> 4f272a50 ( Spacetime )
"battle_state" => db_update.battle_state.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"big_fish_agent_message" => db_update.big_fish_agent_message.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"big_fish_asset_slot" => db_update.big_fish_asset_slot.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
@@ -1441,11 +1438,13 @@ for table_rows in raw.tables {
"puzzle_work_profile" => db_update.puzzle_work_profile.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"quest_log" => db_update.quest_log.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"quest_record" => db_update.quest_record.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"refresh_session" => db_update.refresh_session.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"runtime_setting" => db_update.runtime_setting.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"runtime_snapshot" => db_update.runtime_snapshot.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"story_event" => db_update.story_event.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"story_session" => db_update.story_session.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"treasure_record" => db_update.treasure_record.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"user_account" => db_update.user_account.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
"user_browse_history" => db_update.user_browse_history.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
unknown => { return Err(__sdk::InternalError::unknown_name("table", unknown, "QueryRows").into()); }
}} Ok(db_update)
@@ -1462,6 +1461,7 @@ pub struct AppliedDiff<'r> {
ai_text_chunk: __sdk::TableAppliedDiff<'r, AiTextChunk>,
asset_entity_binding: __sdk::TableAppliedDiff<'r, AssetEntityBinding>,
asset_object: __sdk::TableAppliedDiff<'r, AssetObject>,
auth_identity: __sdk::TableAppliedDiff<'r, AuthIdentity>,
auth_store_snapshot: __sdk::TableAppliedDiff<'r, AuthStoreSnapshot>,
battle_state: __sdk::TableAppliedDiff<'r, BattleState>,
big_fish_agent_message: __sdk::TableAppliedDiff<'r, BigFishAgentMessage>,
@@ -1489,11 +1489,13 @@ pub struct AppliedDiff<'r> {
puzzle_work_profile: __sdk::TableAppliedDiff<'r, PuzzleWorkProfileRow>,
quest_log: __sdk::TableAppliedDiff<'r, QuestLog>,
quest_record: __sdk::TableAppliedDiff<'r, QuestRecord>,
refresh_session: __sdk::TableAppliedDiff<'r, RefreshSession>,
runtime_setting: __sdk::TableAppliedDiff<'r, RuntimeSetting>,
runtime_snapshot: __sdk::TableAppliedDiff<'r, RuntimeSnapshotRow>,
story_event: __sdk::TableAppliedDiff<'r, StoryEvent>,
story_session: __sdk::TableAppliedDiff<'r, StorySession>,
treasure_record: __sdk::TableAppliedDiff<'r, TreasureRecord>,
user_account: __sdk::TableAppliedDiff<'r, UserAccount>,
user_browse_history: __sdk::TableAppliedDiff<'r, UserBrowseHistory>,
__unused: std::marker::PhantomData<&'r ()>,
}
@@ -1511,10 +1513,8 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
callbacks.invoke_table_row_callbacks::<AiTextChunk>("ai_text_chunk", &self.ai_text_chunk, event);
callbacks.invoke_table_row_callbacks::<AssetEntityBinding>("asset_entity_binding", &self.asset_entity_binding, event);
callbacks.invoke_table_row_callbacks::<AssetObject>("asset_object", &self.asset_object, event);
<<<<<<< HEAD
=======
callbacks.invoke_table_row_callbacks::<AuthIdentity>("auth_identity", &self.auth_identity, event);
callbacks.invoke_table_row_callbacks::<AuthStoreSnapshot>("auth_store_snapshot", &self.auth_store_snapshot, event);
>>>>>>> 4f272a50 ( Spacetime )
callbacks.invoke_table_row_callbacks::<BattleState>("battle_state", &self.battle_state, event);
callbacks.invoke_table_row_callbacks::<BigFishAgentMessage>("big_fish_agent_message", &self.big_fish_agent_message, event);
callbacks.invoke_table_row_callbacks::<BigFishAssetSlot>("big_fish_asset_slot", &self.big_fish_asset_slot, event);
@@ -1541,11 +1541,13 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
callbacks.invoke_table_row_callbacks::<PuzzleWorkProfileRow>("puzzle_work_profile", &self.puzzle_work_profile, event);
callbacks.invoke_table_row_callbacks::<QuestLog>("quest_log", &self.quest_log, event);
callbacks.invoke_table_row_callbacks::<QuestRecord>("quest_record", &self.quest_record, event);
callbacks.invoke_table_row_callbacks::<RefreshSession>("refresh_session", &self.refresh_session, event);
callbacks.invoke_table_row_callbacks::<RuntimeSetting>("runtime_setting", &self.runtime_setting, event);
callbacks.invoke_table_row_callbacks::<RuntimeSnapshotRow>("runtime_snapshot", &self.runtime_snapshot, event);
callbacks.invoke_table_row_callbacks::<StoryEvent>("story_event", &self.story_event, event);
callbacks.invoke_table_row_callbacks::<StorySession>("story_session", &self.story_session, event);
callbacks.invoke_table_row_callbacks::<TreasureRecord>("treasure_record", &self.treasure_record, event);
callbacks.invoke_table_row_callbacks::<UserAccount>("user_account", &self.user_account, event);
callbacks.invoke_table_row_callbacks::<UserBrowseHistory>("user_browse_history", &self.user_browse_history, event);
}
}
@@ -2204,6 +2206,7 @@ fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
ai_text_chunk_table::register_table(client_cache);
asset_entity_binding_table::register_table(client_cache);
asset_object_table::register_table(client_cache);
auth_identity_table::register_table(client_cache);
auth_store_snapshot_table::register_table(client_cache);
battle_state_table::register_table(client_cache);
big_fish_agent_message_table::register_table(client_cache);
@@ -2231,11 +2234,13 @@ fn register_tables(client_cache: &mut __sdk::ClientCache<Self>) {
puzzle_work_profile_table::register_table(client_cache);
quest_log_table::register_table(client_cache);
quest_record_table::register_table(client_cache);
refresh_session_table::register_table(client_cache);
runtime_setting_table::register_table(client_cache);
runtime_snapshot_table::register_table(client_cache);
story_event_table::register_table(client_cache);
story_session_table::register_table(client_cache);
treasure_record_table::register_table(client_cache);
user_account_table::register_table(client_cache);
user_browse_history_table::register_table(client_cache);
}
const ALL_TABLE_NAMES: &'static [&'static str] = &[
@@ -2245,6 +2250,7 @@ const ALL_TABLE_NAMES: &'static [&'static str] = &[
"ai_text_chunk",
"asset_entity_binding",
"asset_object",
"auth_identity",
"auth_store_snapshot",
"battle_state",
"big_fish_agent_message",
@@ -2272,11 +2278,13 @@ const ALL_TABLE_NAMES: &'static [&'static str] = &[
"puzzle_work_profile",
"quest_log",
"quest_record",
"refresh_session",
"runtime_setting",
"runtime_snapshot",
"story_event",
"story_session",
"treasure_record",
"user_account",
"user_browse_history",
];
}

View File

@@ -0,0 +1,163 @@
// 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::refresh_session_type::RefreshSession;
/// Table handle for the table `refresh_session`.
///
/// Obtain a handle from the [`RefreshSessionTableAccess::refresh_session`] method on [`super::RemoteTables`],
/// like `ctx.db.refresh_session()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.refresh_session().on_insert(...)`.
pub struct RefreshSessionTableHandle<'ctx> {
imp: __sdk::TableHandle<RefreshSession>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `refresh_session`.
///
/// Implemented for [`super::RemoteTables`].
pub trait RefreshSessionTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`RefreshSessionTableHandle`], which mediates access to the table `refresh_session`.
fn refresh_session(&self) -> RefreshSessionTableHandle<'_>;
}
impl RefreshSessionTableAccess for super::RemoteTables {
fn refresh_session(&self) -> RefreshSessionTableHandle<'_> {
RefreshSessionTableHandle {
imp: self.imp.get_table::<RefreshSession>("refresh_session"),
ctx: std::marker::PhantomData,
}
}
}
pub struct RefreshSessionInsertCallbackId(__sdk::CallbackId);
pub struct RefreshSessionDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for RefreshSessionTableHandle<'ctx> {
type Row = RefreshSession;
type EventContext = super::EventContext;
fn count(&self) -> u64 { self.imp.count() }
fn iter(&self) -> impl Iterator<Item = RefreshSession> + '_ { self.imp.iter() }
type InsertCallbackId = RefreshSessionInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> RefreshSessionInsertCallbackId {
RefreshSessionInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: RefreshSessionInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = RefreshSessionDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> RefreshSessionDeleteCallbackId {
RefreshSessionDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: RefreshSessionDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct RefreshSessionUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for RefreshSessionTableHandle<'ctx> {
type UpdateCallbackId = RefreshSessionUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> RefreshSessionUpdateCallbackId {
RefreshSessionUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: RefreshSessionUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `session_id` unique index on the table `refresh_session`,
/// which allows point queries on the field of the same name
/// via the [`RefreshSessionSessionIdUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.refresh_session().session_id().find(...)`.
pub struct RefreshSessionSessionIdUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<RefreshSession, String>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> RefreshSessionTableHandle<'ctx> {
/// Get a handle on the `session_id` unique index on the table `refresh_session`.
pub fn session_id(&self) -> RefreshSessionSessionIdUnique<'ctx> {
RefreshSessionSessionIdUnique {
imp: self.imp.get_unique_constraint::<String>("session_id"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> RefreshSessionSessionIdUnique<'ctx> {
/// Find the subscribed row whose `session_id` 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<RefreshSession> {
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::<RefreshSession>("refresh_session");
_table.add_unique_constraint::<String>("session_id", |row| &row.session_id);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<RefreshSession>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse(
"TableUpdate<RefreshSession>",
"TableUpdate",
).with_cause(e).into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `RefreshSession`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait refresh_sessionQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `RefreshSession`.
fn refresh_session(&self) -> __sdk::__query_builder::Table<RefreshSession>;
}
impl refresh_sessionQueryTableAccess for __sdk::QueryTableAccessor {
fn refresh_session(&self) -> __sdk::__query_builder::Table<RefreshSession> {
__sdk::__query_builder::Table::new("refresh_session")
}
}

View File

@@ -0,0 +1,91 @@
// 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 RefreshSession {
pub session_id: String,
pub user_id: String,
pub refresh_token_hash: String,
pub issued_by_provider: String,
pub client_info_json: String,
pub expires_at: String,
pub revoked_at: Option::<String>,
pub created_at: String,
pub updated_at: String,
pub last_seen_at: String,
}
impl __sdk::InModule for RefreshSession {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `RefreshSession`.
///
/// Provides typed access to columns for query building.
pub struct RefreshSessionCols {
pub session_id: __sdk::__query_builder::Col<RefreshSession, String>,
pub user_id: __sdk::__query_builder::Col<RefreshSession, String>,
pub refresh_token_hash: __sdk::__query_builder::Col<RefreshSession, String>,
pub issued_by_provider: __sdk::__query_builder::Col<RefreshSession, String>,
pub client_info_json: __sdk::__query_builder::Col<RefreshSession, String>,
pub expires_at: __sdk::__query_builder::Col<RefreshSession, String>,
pub revoked_at: __sdk::__query_builder::Col<RefreshSession, Option::<String>>,
pub created_at: __sdk::__query_builder::Col<RefreshSession, String>,
pub updated_at: __sdk::__query_builder::Col<RefreshSession, String>,
pub last_seen_at: __sdk::__query_builder::Col<RefreshSession, String>,
}
impl __sdk::__query_builder::HasCols for RefreshSession {
type Cols = RefreshSessionCols;
fn cols(table_name: &'static str) -> Self::Cols {
RefreshSessionCols {
session_id: __sdk::__query_builder::Col::new(table_name, "session_id"),
user_id: __sdk::__query_builder::Col::new(table_name, "user_id"),
refresh_token_hash: __sdk::__query_builder::Col::new(table_name, "refresh_token_hash"),
issued_by_provider: __sdk::__query_builder::Col::new(table_name, "issued_by_provider"),
client_info_json: __sdk::__query_builder::Col::new(table_name, "client_info_json"),
expires_at: __sdk::__query_builder::Col::new(table_name, "expires_at"),
revoked_at: __sdk::__query_builder::Col::new(table_name, "revoked_at"),
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
last_seen_at: __sdk::__query_builder::Col::new(table_name, "last_seen_at"),
}
}
}
/// Indexed column accessor struct for the table `RefreshSession`.
///
/// Provides typed access to indexed columns for query building.
pub struct RefreshSessionIxCols {
pub refresh_token_hash: __sdk::__query_builder::IxCol<RefreshSession, String>,
pub session_id: __sdk::__query_builder::IxCol<RefreshSession, String>,
pub user_id: __sdk::__query_builder::IxCol<RefreshSession, String>,
}
impl __sdk::__query_builder::HasIxCols for RefreshSession {
type IxCols = RefreshSessionIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
RefreshSessionIxCols {
refresh_token_hash: __sdk::__query_builder::IxCol::new(table_name, "refresh_token_hash"),
session_id: __sdk::__query_builder::IxCol::new(table_name, "session_id"),
user_id: __sdk::__query_builder::IxCol::new(table_name, "user_id"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for RefreshSession {}

View File

@@ -25,6 +25,10 @@ pub enum RpgAgentOperationType {
GenerateLandmarks,
DeleteCharacters,
DeleteLandmarks,
GenerateRoleAssets,
SyncRoleAssets,

View File

@@ -0,0 +1,163 @@
// 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::user_account_type::UserAccount;
/// Table handle for the table `user_account`.
///
/// Obtain a handle from the [`UserAccountTableAccess::user_account`] method on [`super::RemoteTables`],
/// like `ctx.db.user_account()`.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.user_account().on_insert(...)`.
pub struct UserAccountTableHandle<'ctx> {
imp: __sdk::TableHandle<UserAccount>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the table `user_account`.
///
/// Implemented for [`super::RemoteTables`].
pub trait UserAccountTableAccess {
#[allow(non_snake_case)]
/// Obtain a [`UserAccountTableHandle`], which mediates access to the table `user_account`.
fn user_account(&self) -> UserAccountTableHandle<'_>;
}
impl UserAccountTableAccess for super::RemoteTables {
fn user_account(&self) -> UserAccountTableHandle<'_> {
UserAccountTableHandle {
imp: self.imp.get_table::<UserAccount>("user_account"),
ctx: std::marker::PhantomData,
}
}
}
pub struct UserAccountInsertCallbackId(__sdk::CallbackId);
pub struct UserAccountDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for UserAccountTableHandle<'ctx> {
type Row = UserAccount;
type EventContext = super::EventContext;
fn count(&self) -> u64 { self.imp.count() }
fn iter(&self) -> impl Iterator<Item = UserAccount> + '_ { self.imp.iter() }
type InsertCallbackId = UserAccountInsertCallbackId;
fn on_insert(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> UserAccountInsertCallbackId {
UserAccountInsertCallbackId(self.imp.on_insert(Box::new(callback)))
}
fn remove_on_insert(&self, callback: UserAccountInsertCallbackId) {
self.imp.remove_on_insert(callback.0)
}
type DeleteCallbackId = UserAccountDeleteCallbackId;
fn on_delete(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
) -> UserAccountDeleteCallbackId {
UserAccountDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
}
fn remove_on_delete(&self, callback: UserAccountDeleteCallbackId) {
self.imp.remove_on_delete(callback.0)
}
}
pub struct UserAccountUpdateCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::TableWithPrimaryKey for UserAccountTableHandle<'ctx> {
type UpdateCallbackId = UserAccountUpdateCallbackId;
fn on_update(
&self,
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
) -> UserAccountUpdateCallbackId {
UserAccountUpdateCallbackId(self.imp.on_update(Box::new(callback)))
}
fn remove_on_update(&self, callback: UserAccountUpdateCallbackId) {
self.imp.remove_on_update(callback.0)
}
}
/// Access to the `user_id` unique index on the table `user_account`,
/// which allows point queries on the field of the same name
/// via the [`UserAccountUserIdUnique::find`] method.
///
/// Users are encouraged not to explicitly reference this type,
/// but to directly chain method calls,
/// like `ctx.db.user_account().user_id().find(...)`.
pub struct UserAccountUserIdUnique<'ctx> {
imp: __sdk::UniqueConstraintHandle<UserAccount, String>,
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
}
impl<'ctx> UserAccountTableHandle<'ctx> {
/// Get a handle on the `user_id` unique index on the table `user_account`.
pub fn user_id(&self) -> UserAccountUserIdUnique<'ctx> {
UserAccountUserIdUnique {
imp: self.imp.get_unique_constraint::<String>("user_id"),
phantom: std::marker::PhantomData,
}
}
}
impl<'ctx> UserAccountUserIdUnique<'ctx> {
/// Find the subscribed row whose `user_id` 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<UserAccount> {
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::<UserAccount>("user_account");
_table.add_unique_constraint::<String>("user_id", |row| &row.user_id);
}
#[doc(hidden)]
pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<UserAccount>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse(
"TableUpdate<UserAccount>",
"TableUpdate",
).with_cause(e).into()
})
}
#[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `UserAccount`.
///
/// Implemented for [`__sdk::QueryTableAccessor`].
pub trait user_accountQueryTableAccess {
#[allow(non_snake_case)]
/// Get a query builder for the table `UserAccount`.
fn user_account(&self) -> __sdk::__query_builder::Table<UserAccount>;
}
impl user_accountQueryTableAccess for __sdk::QueryTableAccessor {
fn user_account(&self) -> __sdk::__query_builder::Table<UserAccount> {
__sdk::__query_builder::Table::new("user_account")
}
}

View File

@@ -0,0 +1,97 @@
// 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 UserAccount {
pub user_id: String,
pub public_user_code: String,
pub username: String,
pub display_name: String,
pub phone_number_masked: Option::<String>,
pub phone_number_e_164: Option::<String>,
pub login_method: String,
pub binding_status: String,
pub wechat_bound: bool,
pub password_hash: String,
pub password_login_enabled: bool,
pub token_version: u64,
}
impl __sdk::InModule for UserAccount {
type Module = super::RemoteModule;
}
/// Column accessor struct for the table `UserAccount`.
///
/// Provides typed access to columns for query building.
pub struct UserAccountCols {
pub user_id: __sdk::__query_builder::Col<UserAccount, String>,
pub public_user_code: __sdk::__query_builder::Col<UserAccount, String>,
pub username: __sdk::__query_builder::Col<UserAccount, String>,
pub display_name: __sdk::__query_builder::Col<UserAccount, String>,
pub phone_number_masked: __sdk::__query_builder::Col<UserAccount, Option::<String>>,
pub phone_number_e_164: __sdk::__query_builder::Col<UserAccount, Option::<String>>,
pub login_method: __sdk::__query_builder::Col<UserAccount, String>,
pub binding_status: __sdk::__query_builder::Col<UserAccount, String>,
pub wechat_bound: __sdk::__query_builder::Col<UserAccount, bool>,
pub password_hash: __sdk::__query_builder::Col<UserAccount, String>,
pub password_login_enabled: __sdk::__query_builder::Col<UserAccount, bool>,
pub token_version: __sdk::__query_builder::Col<UserAccount, u64>,
}
impl __sdk::__query_builder::HasCols for UserAccount {
type Cols = UserAccountCols;
fn cols(table_name: &'static str) -> Self::Cols {
UserAccountCols {
user_id: __sdk::__query_builder::Col::new(table_name, "user_id"),
public_user_code: __sdk::__query_builder::Col::new(table_name, "public_user_code"),
username: __sdk::__query_builder::Col::new(table_name, "username"),
display_name: __sdk::__query_builder::Col::new(table_name, "display_name"),
phone_number_masked: __sdk::__query_builder::Col::new(table_name, "phone_number_masked"),
phone_number_e_164: __sdk::__query_builder::Col::new(table_name, "phone_number_e_164"),
login_method: __sdk::__query_builder::Col::new(table_name, "login_method"),
binding_status: __sdk::__query_builder::Col::new(table_name, "binding_status"),
wechat_bound: __sdk::__query_builder::Col::new(table_name, "wechat_bound"),
password_hash: __sdk::__query_builder::Col::new(table_name, "password_hash"),
password_login_enabled: __sdk::__query_builder::Col::new(table_name, "password_login_enabled"),
token_version: __sdk::__query_builder::Col::new(table_name, "token_version"),
}
}
}
/// Indexed column accessor struct for the table `UserAccount`.
///
/// Provides typed access to indexed columns for query building.
pub struct UserAccountIxCols {
pub public_user_code: __sdk::__query_builder::IxCol<UserAccount, String>,
pub user_id: __sdk::__query_builder::IxCol<UserAccount, String>,
pub username: __sdk::__query_builder::IxCol<UserAccount, String>,
}
impl __sdk::__query_builder::HasIxCols for UserAccount {
type IxCols = UserAccountIxCols;
fn ix_cols(table_name: &'static str) -> Self::IxCols {
UserAccountIxCols {
public_user_code: __sdk::__query_builder::IxCol::new(table_name, "public_user_code"),
user_id: __sdk::__query_builder::IxCol::new(table_name, "user_id"),
username: __sdk::__query_builder::IxCol::new(table_name, "username"),
}
}
}
impl __sdk::__query_builder::CanBeLookupTable for UserAccount {}

View File

@@ -1,12 +1,13 @@
use super::*;
use crate::mapper::*;
impl SpacetimeClient {
pub async fn resolve_npc_battle_interaction(
&self,
input: ResolveNpcBattleInteractionInput,
input: crate::mapper::ResolveNpcBattleInteractionInput,
) -> Result<NpcBattleInteractionRecord, SpacetimeClientError> {
validate_npc_battle_interaction_input(&input)?;
let procedure_input = map_resolve_npc_battle_interaction_input(input);
let procedure_input = input.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -23,6 +24,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -1,4 +1,5 @@
use super::*;
use crate::mapper::*;
impl SpacetimeClient {
pub async fn create_puzzle_agent_session(
@@ -28,7 +29,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_puzzle_agent_session(
&self,
session_id: String,
@@ -53,7 +53,6 @@ impl SpacetimeClient {
.await
}
pub async fn submit_puzzle_agent_message(
&self,
input: PuzzleAgentMessageSubmitRecordInput,
@@ -80,7 +79,6 @@ impl SpacetimeClient {
.await
}
pub async fn finalize_puzzle_agent_message(
&self,
input: PuzzleAgentMessageFinalizeRecordInput,
@@ -110,7 +108,6 @@ impl SpacetimeClient {
.await
}
pub async fn compile_puzzle_agent_draft(
&self,
session_id: String,
@@ -137,7 +134,6 @@ impl SpacetimeClient {
.await
}
pub async fn save_puzzle_generated_images(
&self,
input: PuzzleGeneratedImagesSaveRecordInput,
@@ -163,7 +159,6 @@ impl SpacetimeClient {
.await
}
pub async fn select_puzzle_cover_image(
&self,
input: PuzzleSelectCoverImageRecordInput,
@@ -189,7 +184,6 @@ impl SpacetimeClient {
.await
}
pub async fn publish_puzzle_work(
&self,
input: PuzzlePublishRecordInput,
@@ -219,7 +213,6 @@ impl SpacetimeClient {
.await
}
pub async fn list_puzzle_works(
&self,
owner_user_id: String,
@@ -239,7 +232,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_puzzle_work_detail(
&self,
profile_id: String,
@@ -260,7 +252,6 @@ impl SpacetimeClient {
.await
}
pub async fn update_puzzle_work(
&self,
input: PuzzleWorkUpsertRecordInput,
@@ -289,7 +280,6 @@ impl SpacetimeClient {
.await
}
pub async fn list_puzzle_gallery(
&self,
) -> Result<Vec<PuzzleWorkProfileRecord>, SpacetimeClientError> {
@@ -306,7 +296,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_puzzle_gallery_detail(
&self,
profile_id: String,
@@ -327,7 +316,6 @@ impl SpacetimeClient {
.await
}
pub async fn start_puzzle_run(
&self,
input: PuzzleRunStartRecordInput,
@@ -352,7 +340,6 @@ impl SpacetimeClient {
.await
}
pub async fn get_puzzle_run(
&self,
run_id: String,
@@ -376,7 +363,6 @@ impl SpacetimeClient {
.await
}
pub async fn swap_puzzle_pieces(
&self,
input: PuzzleRunSwapRecordInput,
@@ -402,7 +388,6 @@ impl SpacetimeClient {
.await
}
pub async fn drag_puzzle_piece_or_group(
&self,
input: PuzzleRunDragRecordInput,
@@ -430,7 +415,6 @@ impl SpacetimeClient {
.await
}
pub async fn advance_puzzle_next_level(
&self,
input: PuzzleRunNextLevelRecordInput,
@@ -454,6 +438,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -5,10 +5,9 @@ impl SpacetimeClient {
&self,
user_id: String,
) -> Result<RuntimeSettingsRecord, SpacetimeClientError> {
let procedure_input = map_runtime_setting_get_input(
build_runtime_setting_get_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_setting_get_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().get_runtime_setting_or_default_then(
@@ -24,15 +23,13 @@ impl SpacetimeClient {
.await
}
pub async fn list_platform_browse_history(
&self,
user_id: String,
) -> Result<Vec<RuntimeBrowseHistoryRecord>, SpacetimeClientError> {
let procedure_input = map_runtime_browse_history_list_input(
build_runtime_browse_history_list_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_browse_history_list_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().list_platform_browse_history_then(
@@ -48,15 +45,13 @@ impl SpacetimeClient {
.await
}
pub async fn get_profile_dashboard(
&self,
user_id: String,
) -> Result<RuntimeProfileDashboardRecord, SpacetimeClientError> {
let procedure_input = map_runtime_profile_dashboard_get_input(
build_runtime_profile_dashboard_get_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_profile_dashboard_get_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().get_profile_dashboard_then(
@@ -72,15 +67,13 @@ impl SpacetimeClient {
.await
}
pub async fn list_profile_wallet_ledger(
&self,
user_id: String,
) -> Result<Vec<RuntimeProfileWalletLedgerEntryRecord>, SpacetimeClientError> {
let procedure_input = map_runtime_profile_wallet_ledger_list_input(
build_runtime_profile_wallet_ledger_list_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_profile_wallet_ledger_list_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().list_profile_wallet_ledger_then(
@@ -96,15 +89,13 @@ impl SpacetimeClient {
.await
}
pub async fn get_profile_play_stats(
&self,
user_id: String,
) -> Result<RuntimeProfilePlayStatsRecord, SpacetimeClientError> {
let procedure_input = map_runtime_profile_play_stats_get_input(
build_runtime_profile_play_stats_get_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_profile_play_stats_get_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().get_profile_play_stats_then(
@@ -120,15 +111,13 @@ impl SpacetimeClient {
.await
}
pub async fn get_runtime_snapshot(
&self,
user_id: String,
) -> Result<Option<RuntimeSnapshotRecord>, SpacetimeClientError> {
let procedure_input = map_runtime_snapshot_get_input(
build_runtime_snapshot_get_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_snapshot_get_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -143,7 +132,6 @@ impl SpacetimeClient {
.await
}
pub async fn put_runtime_snapshot(
&self,
user_id: String,
@@ -153,17 +141,16 @@ impl SpacetimeClient {
current_story: Option<serde_json::Value>,
updated_at_micros: i64,
) -> Result<RuntimeSnapshotRecord, SpacetimeClientError> {
let procedure_input = map_runtime_snapshot_upsert_input(
build_runtime_snapshot_upsert_input(
user_id,
saved_at_micros,
bottom_tab,
game_state,
current_story,
updated_at_micros,
)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_snapshot_upsert_input(
user_id,
saved_at_micros,
bottom_tab,
game_state,
current_story,
updated_at_micros,
)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -178,15 +165,13 @@ impl SpacetimeClient {
.await
}
pub async fn delete_runtime_snapshot(
&self,
user_id: String,
) -> Result<bool, SpacetimeClientError> {
let procedure_input = map_runtime_snapshot_delete_input(
build_runtime_snapshot_delete_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_snapshot_delete_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -201,15 +186,13 @@ impl SpacetimeClient {
.await
}
pub async fn list_profile_save_archives(
&self,
user_id: String,
) -> Result<Vec<RuntimeProfileSaveArchiveRecord>, SpacetimeClientError> {
let procedure_input = map_runtime_profile_save_archive_list_input(
build_runtime_profile_save_archive_list_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_profile_save_archive_list_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().list_profile_save_archives_then(
@@ -225,17 +208,15 @@ impl SpacetimeClient {
.await
}
pub async fn resume_profile_save_archive(
&self,
user_id: String,
world_key: String,
) -> Result<(RuntimeProfileSaveArchiveRecord, RuntimeSnapshotRecord), SpacetimeClientError>
{
let procedure_input = map_runtime_profile_save_archive_resume_input(
build_runtime_profile_save_archive_resume_input(user_id, world_key)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_profile_save_archive_resume_input(user_id, world_key)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -250,23 +231,21 @@ impl SpacetimeClient {
.await
}
pub async fn put_runtime_settings(
&self,
user_id: String,
music_volume: f32,
platform_theme: RuntimePlatformTheme,
platform_theme: DomainRuntimePlatformTheme,
updated_at_micros: i64,
) -> Result<RuntimeSettingsRecord, SpacetimeClientError> {
let procedure_input = map_runtime_setting_upsert_input(
build_runtime_setting_upsert_input(
user_id,
music_volume,
platform_theme,
updated_at_micros,
)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_setting_upsert_input(
user_id,
music_volume,
platform_theme,
updated_at_micros,
)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -281,17 +260,16 @@ impl SpacetimeClient {
.await
}
pub async fn upsert_platform_browse_history_entries(
&self,
user_id: String,
entries: Vec<module_runtime::RuntimeBrowseHistoryWriteInput>,
updated_at_micros: i64,
) -> Result<Vec<RuntimeBrowseHistoryRecord>, SpacetimeClientError> {
let procedure_input = map_runtime_browse_history_sync_input(
let procedure_input =
build_runtime_browse_history_sync_input(user_id, entries, updated_at_micros)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -309,15 +287,13 @@ impl SpacetimeClient {
.await
}
pub async fn clear_platform_browse_history(
&self,
user_id: String,
) -> Result<Vec<RuntimeBrowseHistoryRecord>, SpacetimeClientError> {
let procedure_input = map_runtime_browse_history_clear_input(
build_runtime_browse_history_clear_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_runtime_browse_history_clear_input(user_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection
@@ -334,6 +310,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -11,18 +11,17 @@ impl SpacetimeClient {
opening_summary: Option<String>,
created_at_micros: i64,
) -> Result<StorySessionResultRecord, SpacetimeClientError> {
let procedure_input = map_story_session_input(
build_story_session_input(
story_session_id,
runtime_session_id,
actor_user_id,
world_profile_id,
initial_prompt,
opening_summary,
created_at_micros,
)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_story_session_input(
story_session_id,
runtime_session_id,
actor_user_id,
world_profile_id,
initial_prompt,
opening_summary,
created_at_micros,
)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().begin_story_session_and_return_then(
@@ -38,7 +37,6 @@ impl SpacetimeClient {
.await
}
pub async fn continue_story(
&self,
story_session_id: String,
@@ -47,16 +45,15 @@ impl SpacetimeClient {
choice_function_id: Option<String>,
updated_at_micros: i64,
) -> Result<StorySessionResultRecord, SpacetimeClientError> {
let procedure_input = map_story_continue_input(
build_story_continue_input(
story_session_id,
event_id,
narrative_text,
choice_function_id,
updated_at_micros,
)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_story_continue_input(
story_session_id,
event_id,
narrative_text,
choice_function_id,
updated_at_micros,
)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().continue_story_and_return_then(
@@ -72,15 +69,13 @@ impl SpacetimeClient {
.await
}
pub async fn get_story_session_state(
&self,
story_session_id: String,
) -> Result<StorySessionStateRecord, SpacetimeClientError> {
let procedure_input = map_story_session_state_input(
build_story_session_state_input(story_session_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
);
let procedure_input = build_story_session_state_input(story_session_id)
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into();
self.call_after_connect(move |connection, sender| {
connection.procedures().get_story_session_state_then(
@@ -95,6 +90,4 @@ impl SpacetimeClient {
})
.await
}
}

View File

@@ -1,4 +1,6 @@
use crate::*;
use serde::{Deserialize, Serialize};
use serde_json::Value;
const AUTH_STORE_SNAPSHOT_ID: &str = "default";
@@ -21,6 +23,20 @@ pub struct AuthStoreSnapshotProcedureResult {
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct AuthStoreSnapshotImportRecord {
pub imported_user_count: u32,
pub imported_identity_count: u32,
pub imported_refresh_session_count: u32,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct AuthStoreSnapshotImportProcedureResult {
pub ok: bool,
pub record: Option<AuthStoreSnapshotImportRecord>,
pub error_message: Option<String>,
}
#[spacetimedb::table(accessor = auth_store_snapshot)]
pub struct AuthStoreSnapshot {
#[primary_key]
@@ -29,6 +45,63 @@ pub struct AuthStoreSnapshot {
pub(crate) updated_at: Timestamp,
}
#[spacetimedb::table(
accessor = user_account,
index(accessor = by_user_account_username, btree(columns = [username])),
index(accessor = by_user_account_public_code, btree(columns = [public_user_code]))
)]
pub struct UserAccount {
#[primary_key]
pub(crate) user_id: String,
pub(crate) public_user_code: String,
pub(crate) username: String,
pub(crate) display_name: String,
pub(crate) phone_number_masked: Option<String>,
pub(crate) phone_number_e164: Option<String>,
pub(crate) login_method: String,
pub(crate) binding_status: String,
pub(crate) wechat_bound: bool,
pub(crate) password_hash: String,
pub(crate) password_login_enabled: bool,
pub(crate) token_version: u64,
}
#[spacetimedb::table(
accessor = auth_identity,
index(accessor = by_auth_identity_user_id, btree(columns = [user_id])),
index(accessor = by_auth_identity_provider_uid, btree(columns = [provider, provider_uid]))
)]
pub struct AuthIdentity {
#[primary_key]
pub(crate) identity_id: String,
pub(crate) user_id: String,
pub(crate) provider: String,
pub(crate) provider_uid: String,
pub(crate) provider_union_id: Option<String>,
pub(crate) phone_e164: Option<String>,
pub(crate) display_name: Option<String>,
pub(crate) avatar_url: Option<String>,
}
#[spacetimedb::table(
accessor = refresh_session,
index(accessor = by_refresh_session_user_id, btree(columns = [user_id])),
index(accessor = by_refresh_session_token_hash, btree(columns = [refresh_token_hash]))
)]
pub struct RefreshSession {
#[primary_key]
pub(crate) session_id: String,
pub(crate) user_id: String,
pub(crate) refresh_token_hash: String,
pub(crate) issued_by_provider: String,
pub(crate) client_info_json: String,
pub(crate) expires_at: String,
pub(crate) revoked_at: Option<String>,
pub(crate) created_at: String,
pub(crate) updated_at: String,
pub(crate) last_seen_at: String,
}
// Axum 启动恢复认证状态时读取当前快照;记录不存在代表尚未产生登录态。
#[spacetimedb::procedure]
pub fn get_auth_store_snapshot(ctx: &mut ProcedureContext) -> AuthStoreSnapshotProcedureResult {
@@ -66,6 +139,43 @@ pub fn upsert_auth_store_snapshot(
}
}
#[spacetimedb::procedure]
pub fn import_auth_store_snapshot(
ctx: &mut ProcedureContext,
) -> AuthStoreSnapshotImportProcedureResult {
match ctx.try_with_tx(|tx| import_auth_store_snapshot_tx(tx)) {
Ok(record) => AuthStoreSnapshotImportProcedureResult {
ok: true,
record: Some(record),
error_message: None,
},
Err(message) => AuthStoreSnapshotImportProcedureResult {
ok: false,
record: None,
error_message: Some(message),
},
}
}
// Axum ??????????????? module-auth ????????????????
#[spacetimedb::procedure]
pub fn export_auth_store_snapshot_from_tables(
ctx: &mut ProcedureContext,
) -> AuthStoreSnapshotProcedureResult {
match ctx.try_with_tx(|tx| export_auth_store_snapshot_from_tables_tx(tx)) {
Ok(record) => AuthStoreSnapshotProcedureResult {
ok: true,
record: Some(record),
error_message: None,
},
Err(message) => AuthStoreSnapshotProcedureResult {
ok: false,
record: None,
error_message: Some(message),
},
}
}
fn get_auth_store_snapshot_tx(ctx: &ReducerContext) -> Result<AuthStoreSnapshotRecord, String> {
Ok(
match ctx
@@ -120,3 +230,326 @@ fn upsert_auth_store_snapshot_tx(
updated_at_micros: Some(input.updated_at_micros),
})
}
fn import_auth_store_snapshot_tx(
ctx: &ReducerContext,
) -> Result<AuthStoreSnapshotImportRecord, String> {
let snapshot = ctx
.db
.auth_store_snapshot()
.snapshot_id()
.find(&AUTH_STORE_SNAPSHOT_ID.to_string())
.ok_or_else(|| "认证快照不存在,无法导入正式表".to_string())?;
let parsed = serde_json::from_str::<PersistentAuthStoreSnapshot>(&snapshot.snapshot_json)
.map_err(|error| format!("认证快照 JSON 解析失败:{error}"))?;
clear_auth_target_tables(ctx);
let mut imported_user_count = 0_u32;
let mut imported_identity_count = 0_u32;
let mut imported_refresh_session_count = 0_u32;
for stored_user in parsed.users_by_username.into_values() {
let user = stored_user.user;
ctx.db.user_account().insert(UserAccount {
user_id: user.id.clone(),
public_user_code: user.public_user_code,
username: user.username,
display_name: user.display_name,
phone_number_masked: user.phone_number_masked,
phone_number_e164: stored_user.phone_number.clone(),
login_method: user.login_method,
binding_status: user.binding_status,
wechat_bound: user.wechat_bound,
password_hash: stored_user.password_hash,
password_login_enabled: stored_user.password_login_enabled,
token_version: user.token_version,
});
imported_user_count += 1;
if let Some(phone_number) = stored_user.phone_number {
ctx.db.auth_identity().insert(AuthIdentity {
identity_id: format!("authi_phone_{}", sanitize_identity_component(&phone_number)),
user_id: user.id,
provider: "phone".to_string(),
provider_uid: phone_number.clone(),
provider_union_id: None,
phone_e164: Some(phone_number),
display_name: None,
avatar_url: None,
});
imported_identity_count += 1;
}
}
for identity in parsed.wechat_identity_by_provider_uid.into_values() {
ctx.db.auth_identity().insert(AuthIdentity {
identity_id: format!(
"authi_wechat_{}",
sanitize_identity_component(&identity.provider_uid)
),
user_id: identity.user_id,
provider: "wechat".to_string(),
provider_uid: identity.provider_uid,
provider_union_id: identity.provider_union_id,
phone_e164: None,
display_name: identity.display_name,
avatar_url: identity.avatar_url,
});
imported_identity_count += 1;
}
for stored_session in parsed.sessions_by_id.into_values() {
let session = stored_session.session;
let client_info_json = serde_json::to_string(&session.client_info)
.map_err(|error| format!("客户端身份序列化失败:{error}"))?;
ctx.db.refresh_session().insert(RefreshSession {
session_id: session.session_id,
user_id: session.user_id,
refresh_token_hash: session.refresh_token_hash,
issued_by_provider: session.issued_by_provider,
client_info_json,
expires_at: session.expires_at,
revoked_at: session.revoked_at,
created_at: session.created_at,
updated_at: session.updated_at,
last_seen_at: session.last_seen_at,
});
imported_refresh_session_count += 1;
}
Ok(AuthStoreSnapshotImportRecord {
imported_user_count,
imported_identity_count,
imported_refresh_session_count,
})
}
fn export_auth_store_snapshot_from_tables_tx(
ctx: &ReducerContext,
) -> Result<AuthStoreSnapshotRecord, String> {
let users = ctx.db.user_account().iter().collect::<Vec<_>>();
let identities = ctx.db.auth_identity().iter().collect::<Vec<_>>();
let sessions = ctx.db.refresh_session().iter().collect::<Vec<_>>();
if users.is_empty() && identities.is_empty() && sessions.is_empty() {
return Ok(AuthStoreSnapshotRecord {
snapshot_json: None,
updated_at_micros: None,
});
}
let mut phone_identity_by_user_id = std::collections::HashMap::new();
let mut phone_to_user_id = std::collections::HashMap::new();
let mut wechat_identity_by_provider_uid = std::collections::HashMap::new();
let mut user_id_by_provider_union_id = std::collections::HashMap::new();
for identity in identities {
match identity.provider.as_str() {
"phone" => {
let phone_number = identity
.phone_e164
.clone()
.unwrap_or_else(|| identity.provider_uid.clone());
phone_to_user_id.insert(phone_number.clone(), identity.user_id.clone());
phone_identity_by_user_id.insert(identity.user_id, phone_number);
}
"wechat" => {
if let Some(union_id) = identity.provider_union_id.clone() {
user_id_by_provider_union_id.insert(union_id, identity.user_id.clone());
}
wechat_identity_by_provider_uid.insert(
identity.provider_uid.clone(),
StoredWechatIdentitySnapshot {
user_id: identity.user_id,
provider_uid: identity.provider_uid,
provider_union_id: identity.provider_union_id,
display_name: identity.display_name,
avatar_url: identity.avatar_url,
},
);
}
_ => {}
}
}
let mut next_user_id = 1_u64;
let mut users_by_username = std::collections::HashMap::new();
for user in users {
if let Some(numeric_id) = user
.user_id
.strip_prefix("user_")
.and_then(|value| value.parse::<u64>().ok())
{
next_user_id = next_user_id.max(numeric_id.saturating_add(1));
}
let auth_user = AuthUserSnapshot {
id: user.user_id.clone(),
public_user_code: user.public_user_code,
username: user.username.clone(),
display_name: user.display_name,
phone_number_masked: user.phone_number_masked,
login_method: user.login_method,
binding_status: user.binding_status,
wechat_bound: user.wechat_bound,
token_version: user.token_version,
};
users_by_username.insert(
user.username,
StoredPasswordUserSnapshot {
user: auth_user,
password_hash: user.password_hash,
password_login_enabled: user.password_login_enabled,
phone_number: user
.phone_number_e164
.or_else(|| phone_identity_by_user_id.remove(&user.user_id)),
},
);
}
let mut sessions_by_id = std::collections::HashMap::new();
let mut session_id_by_refresh_token_hash = std::collections::HashMap::new();
for session in sessions {
let client_info = serde_json::from_str::<Value>(&session.client_info_json)
.map_err(|error| format!("refresh session ????? JSON ?????{error}"))?;
session_id_by_refresh_token_hash.insert(
session.refresh_token_hash.clone(),
session.session_id.clone(),
);
sessions_by_id.insert(
session.session_id.clone(),
StoredRefreshSessionSnapshot {
session: RefreshSessionSnapshot {
session_id: session.session_id,
user_id: session.user_id,
refresh_token_hash: session.refresh_token_hash,
issued_by_provider: session.issued_by_provider,
client_info,
expires_at: session.expires_at,
revoked_at: session.revoked_at,
created_at: session.created_at,
updated_at: session.updated_at,
last_seen_at: session.last_seen_at,
},
},
);
}
let snapshot = PersistentAuthStoreSnapshot {
next_user_id,
users_by_username,
phone_to_user_id,
sessions_by_id,
session_id_by_refresh_token_hash,
wechat_identity_by_provider_uid,
user_id_by_provider_union_id,
};
let snapshot_json =
serde_json::to_string_pretty(&snapshot).map_err(|error| format!("?????????????{error}"))?;
Ok(AuthStoreSnapshotRecord {
snapshot_json: Some(snapshot_json),
updated_at_micros: None,
})
}
fn clear_auth_target_tables(ctx: &ReducerContext) {
for row in ctx.db.refresh_session().iter().collect::<Vec<_>>() {
ctx.db
.refresh_session()
.session_id()
.delete(&row.session_id);
}
for row in ctx.db.auth_identity().iter().collect::<Vec<_>>() {
ctx.db
.auth_identity()
.identity_id()
.delete(&row.identity_id);
}
for row in ctx.db.user_account().iter().collect::<Vec<_>>() {
ctx.db.user_account().user_id().delete(&row.user_id);
}
}
fn sanitize_identity_component(value: &str) -> String {
let sanitized = value
.chars()
.map(|character| {
if character.is_ascii_alphanumeric() {
character
} else {
'_'
}
})
.collect::<String>();
sanitized.trim_matches('_').to_string()
}
#[derive(Deserialize, Serialize)]
struct PersistentAuthStoreSnapshot {
#[serde(default = "default_next_user_id")]
next_user_id: u64,
users_by_username: std::collections::HashMap<String, StoredPasswordUserSnapshot>,
#[serde(default)]
phone_to_user_id: std::collections::HashMap<String, String>,
sessions_by_id: std::collections::HashMap<String, StoredRefreshSessionSnapshot>,
#[serde(default)]
session_id_by_refresh_token_hash: std::collections::HashMap<String, String>,
wechat_identity_by_provider_uid:
std::collections::HashMap<String, StoredWechatIdentitySnapshot>,
#[serde(default)]
user_id_by_provider_union_id: std::collections::HashMap<String, String>,
}
fn default_next_user_id() -> u64 {
1
}
#[derive(Deserialize, Serialize)]
struct StoredPasswordUserSnapshot {
user: AuthUserSnapshot,
password_hash: String,
#[serde(default)]
password_login_enabled: bool,
phone_number: Option<String>,
}
#[derive(Deserialize, Serialize)]
struct AuthUserSnapshot {
id: String,
public_user_code: String,
username: String,
display_name: String,
phone_number_masked: Option<String>,
login_method: String,
binding_status: String,
wechat_bound: bool,
token_version: u64,
}
#[derive(Deserialize, Serialize)]
struct StoredWechatIdentitySnapshot {
user_id: String,
provider_uid: String,
provider_union_id: Option<String>,
display_name: Option<String>,
avatar_url: Option<String>,
}
#[derive(Deserialize, Serialize)]
struct StoredRefreshSessionSnapshot {
session: RefreshSessionSnapshot,
}
#[derive(Deserialize, Serialize)]
struct RefreshSessionSnapshot {
session_id: String,
user_id: String,
refresh_token_hash: String,
issued_by_provider: String,
client_info: Value,
expires_at: String,
revoked_at: Option<String>,
created_at: String,
updated_at: String,
last_seen_at: String,
}