moved the AppState to lib.rs and refactored accordingly
This commit is contained in:
@@ -6,9 +6,9 @@ use surrealdb::Notification;
|
|||||||
use tauri::{AppHandle, Emitter, State};
|
use tauri::{AppHandle, Emitter, State};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::db::AppState;
|
|
||||||
use crate::error::{into_err, AppError};
|
use crate::error::{into_err, AppError};
|
||||||
use crate::models::{Message, MessageReaction, MessageReactionSummary, Room, User};
|
use crate::models::{Message, MessageReaction, MessageReactionSummary, Room, User};
|
||||||
|
use crate::AppState;
|
||||||
|
|
||||||
const DEFAULT_PAGE_SIZE: i64 = 50;
|
const DEFAULT_PAGE_SIZE: i64 = 50;
|
||||||
const MAX_PAGE_SIZE: i64 = 100;
|
const MAX_PAGE_SIZE: i64 = 100;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use tauri::{AppHandle, State};
|
use tauri::{AppHandle, State};
|
||||||
use tauri_plugin_store::StoreExt;
|
use tauri_plugin_store::StoreExt;
|
||||||
|
|
||||||
use crate::db::{AppState, SURREAL_ACCESS, SURREAL_DB, SURREAL_NS};
|
use crate::db::{SURREAL_ACCESS, SURREAL_DB, SURREAL_NS};
|
||||||
use crate::error::{into_err, AppError};
|
use crate::error::{into_err, AppError};
|
||||||
use crate::models::{Contact, User};
|
use crate::models::{Contact, User};
|
||||||
|
use crate::AppState;
|
||||||
|
|
||||||
const SESSION_STORE: &str = "session.json";
|
const SESSION_STORE: &str = "session.json";
|
||||||
const TOKEN_KEY: &str = "token";
|
const TOKEN_KEY: &str = "token";
|
||||||
@@ -86,7 +87,6 @@ pub async fn signup(
|
|||||||
};
|
};
|
||||||
let token = state.db.signup(credentials).await.map_err(into_err)?;
|
let token = state.db.signup(credentials).await.map_err(into_err)?;
|
||||||
let token_str = token.access.into_insecure_token();
|
let token_str = token.access.into_insecure_token();
|
||||||
*state.token.lock().unwrap() = Some(token_str.clone());
|
|
||||||
save_token(&app_handle, &token_str)?;
|
save_token(&app_handle, &token_str)?;
|
||||||
|
|
||||||
let mut result: Vec<User> = state
|
let mut result: Vec<User> = state
|
||||||
@@ -130,7 +130,6 @@ pub async fn signin(
|
|||||||
.map_err(into_err)?
|
.map_err(into_err)?
|
||||||
.access
|
.access
|
||||||
.into_insecure_token();
|
.into_insecure_token();
|
||||||
*state.token.lock().unwrap() = Some(token_str.clone());
|
|
||||||
save_token(&app_handle, &token_str)?;
|
save_token(&app_handle, &token_str)?;
|
||||||
Ok(token_str)
|
Ok(token_str)
|
||||||
}
|
}
|
||||||
@@ -139,7 +138,6 @@ pub async fn signin(
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn signout(state: State<'_, AppState>, app_handle: AppHandle) -> Result<(), String> {
|
pub async fn signout(state: State<'_, AppState>, app_handle: AppHandle) -> Result<(), String> {
|
||||||
state.db.invalidate().await.map_err(into_err)?;
|
state.db.invalidate().await.map_err(into_err)?;
|
||||||
*state.token.lock().unwrap() = None;
|
|
||||||
clear_token(&app_handle)?;
|
clear_token(&app_handle)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -162,8 +160,6 @@ pub async fn restore_session(
|
|||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
*state.token.lock().unwrap() = Some(token_str);
|
|
||||||
|
|
||||||
let mut result: Vec<User> = state
|
let mut result: Vec<User> = state
|
||||||
.db
|
.db
|
||||||
.query("SELECT * FROM $auth")
|
.query("SELECT * FROM $auth")
|
||||||
@@ -178,7 +174,6 @@ pub async fn restore_session(
|
|||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let _ = clear_token(&app_handle);
|
let _ = clear_token(&app_handle);
|
||||||
*state.token.lock().unwrap() = None;
|
|
||||||
Err(AppError::Auth("session expired, please sign in again".into()).to_string())
|
Err(AppError::Auth("session expired, please sign in again".into()).to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::{Arc, LazyLock, Mutex};
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use surrealdb::engine::remote::ws::{Client, Ws, Wss};
|
use surrealdb::engine::remote::ws::{Client, Ws, Wss};
|
||||||
use surrealdb::Surreal;
|
use surrealdb::Surreal;
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use crate::error::AppError;
|
use crate::error::AppError;
|
||||||
|
|
||||||
// This should set the env variable correctly both during compile time and runtime (for development).
|
|
||||||
pub static SURREAL_URL: LazyLock<String> = LazyLock::new(|| {
|
pub static SURREAL_URL: LazyLock<String> = LazyLock::new(|| {
|
||||||
option_env!("SURREAL_URL")
|
option_env!("SURREAL_URL")
|
||||||
.map(str::to_string)
|
.map(str::to_string)
|
||||||
@@ -33,19 +29,6 @@ pub static SURREAL_ACCESS: LazyLock<String> = LazyLock::new(|| {
|
|||||||
.unwrap_or_else(|| env::var("SURREAL_ACCESS").unwrap_or_else(|_| "account".to_string()))
|
.unwrap_or_else(|| env::var("SURREAL_ACCESS").unwrap_or_else(|_| "account".to_string()))
|
||||||
});
|
});
|
||||||
|
|
||||||
pub struct AppState {
|
|
||||||
/// Long-lived authenticated WebSocket connection to SurrealDB.
|
|
||||||
pub db: Arc<Surreal<Client>>,
|
|
||||||
/// JWT token from Record Auth signin. Used to re-authenticate on reconnect.
|
|
||||||
/// std::sync::Mutex is intentional: lock is acquired and released before any .await.
|
|
||||||
pub token: Mutex<Option<String>>,
|
|
||||||
/// Active LIVE query tasks keyed by their SurrealDB LIVE query UUID.
|
|
||||||
/// Abort a handle + KILL the query to clean up.
|
|
||||||
/// std::sync::Mutex is intentional: guards are never held across .await points.
|
|
||||||
/// If a future command needs to lock across .await, switch to tokio::sync::Mutex.
|
|
||||||
pub subscriptions: Mutex<HashMap<Uuid, JoinHandle<()>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Connect to SurrealDB over WebSocket and select namespace/database.
|
/// Connect to SurrealDB over WebSocket and select namespace/database.
|
||||||
/// URL may include protocol prefix: `ws://`, `wss://`, `http://`, or `https://`.
|
/// URL may include protocol prefix: `ws://`, `wss://`, `http://`, or `https://`.
|
||||||
/// `wss://` and `https://` use TLS; others use plain WebSocket.
|
/// `wss://` and `https://` use TLS; others use plain WebSocket.
|
||||||
|
|||||||
@@ -1,14 +1,24 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use surrealdb::engine::remote::ws::Client;
|
||||||
|
use surrealdb::Surreal;
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod db;
|
mod db;
|
||||||
mod error;
|
mod error;
|
||||||
mod models;
|
mod models;
|
||||||
|
|
||||||
use db::{init_db, AppState, SURREAL_DB, SURREAL_NS, SURREAL_URL};
|
use db::{init_db, SURREAL_DB, SURREAL_NS, SURREAL_URL};
|
||||||
|
|
||||||
|
pub struct AppState {
|
||||||
|
pub db: Arc<Surreal<Client>>,
|
||||||
|
/// std::sync::Mutex is intentional: guards are never held across .await points.
|
||||||
|
pub subscriptions: Mutex<HashMap<Uuid, JoinHandle<()>>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
@@ -28,7 +38,6 @@ pub fn run() {
|
|||||||
|
|
||||||
let state = AppState {
|
let state = AppState {
|
||||||
db: Arc::new(surreal),
|
db: Arc::new(surreal),
|
||||||
token: Mutex::new(None),
|
|
||||||
subscriptions: Mutex::new(HashMap::new()),
|
subscriptions: Mutex::new(HashMap::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user