mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bb1e23f76 | ||
|
|
0c623b58ff | ||
|
|
2c56624e45 | ||
|
|
8f4e8c5b1d | ||
|
|
68caef8e1f |
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n UPDATE tasks\n SET is_dismissed_by_user = 1\n WHERE id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "13d435d8f681b73e4080748dcef0579e246e41049af67e1bd79ffc06aa6ba974"
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n id,\n task_status,\n task_type,\n model_type,\n provider,\n provider_job_id,\n frontend_caller,\n frontend_subscriber_id,\n frontend_subscriber_payload,\n created_at as \"created_at: DateTime<Utc>\",\n updated_at as \"updated_at: DateTime<Utc>\",\n completed_at as \"completed_at: DateTime<Utc>\"\n FROM tasks\n WHERE is_dismissed_by_user == 0\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "task_status",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "task_type",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "model_type",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "provider",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "provider_job_id",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "frontend_caller",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "frontend_subscriber_id",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "frontend_subscriber_payload",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at: DateTime<Utc>",
|
||||
"ordinal": 9,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "updated_at: DateTime<Utc>",
|
||||
"ordinal": 10,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "completed_at: DateTime<Utc>",
|
||||
"ordinal": 11,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "a142dc3fdf5b6e741c268d8f2e9996a28c214f5835681297d58a9431da8de939"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
-- noinspection SqlDialectInspectionForFile
|
||||
-- noinspection SqlNoDataSourceInspectionForFile
|
||||
-- noinspection SqlResolveForFile
|
||||
|
||||
select
|
||||
u.display_name,
|
||||
count(*) as sessions,
|
||||
a.session_duration_seconds / 60 / 60 as hours,
|
||||
a.measurement_count,
|
||||
u.email_address,
|
||||
a.os_platform,
|
||||
a.os_version,
|
||||
u.created_at,
|
||||
u.maybe_source,
|
||||
a.last_active_at
|
||||
from analytics_app_sessions as a
|
||||
left outer join users as u
|
||||
on a.user_token = u.token
|
||||
group by a.user_token
|
||||
order by hours desc;
|
||||
@@ -9,6 +9,7 @@
|
||||
-- tasks_v1.sqlite - initial version
|
||||
-- tasks_v2.sqlite - added model_type (nullable)
|
||||
-- tasks_v3.sqlite - added frontend_caller, comments
|
||||
-- tasks_v4.sqlite - added is_dismissed_by_user
|
||||
|
||||
CREATE TABLE tasks (
|
||||
-- Task auto-incrementing primary key.
|
||||
@@ -50,6 +51,9 @@ CREATE TABLE tasks (
|
||||
-- will be re-emitted back to the frontend.
|
||||
frontend_subscriber_payload TEXT,
|
||||
|
||||
-- Whether the user has dismissed the task from view.
|
||||
is_dismissed_by_user INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
created_at INTEGER NOT NULL DEFAULT (unixepoch('now')),
|
||||
updated_at INTEGER NOT NULL DEFAULT (unixepoch('now')),
|
||||
completed_at INTEGER DEFAULT NULL
|
||||
|
||||
@@ -7,4 +7,5 @@ pub mod load_without_cors_command;
|
||||
pub mod media_files;
|
||||
pub mod platform_info_command;
|
||||
pub mod providers;
|
||||
pub mod response;
|
||||
pub mod response;
|
||||
pub mod task_queue;
|
||||
@@ -0,0 +1,92 @@
|
||||
use crate::core::commands::response::shorthand::ResponseOrErrorMessage;
|
||||
use crate::core::commands::response::success_response_wrapper::SerializeMarker;
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::provider_priority::{Provider, ProviderPriorityStore};
|
||||
use crate::core::state::task_database::TaskDatabase;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::fal::state::fal_task_queue::FalTaskQueue;
|
||||
use crate::services::sora::state::sora_task_queue::SoraTaskQueue;
|
||||
use crate::services::storyteller::state::storyteller_credential_manager::StorytellerCredentialManager;
|
||||
use chrono::{DateTime, Utc};
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
use enums::tauri::tasks::task_model_type::TaskModelType;
|
||||
use enums::tauri::tasks::task_status::TaskStatus;
|
||||
use enums::tauri::tasks::task_type::TaskType;
|
||||
use errors::AnyhowResult;
|
||||
use log::{error, info, warn};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sqlite_tasks::queries::list_tasks_for_frontend::list_tasks_for_frontend;
|
||||
use storyteller_client::endpoints::media_files::delete_media_file::delete_media_file;
|
||||
use tauri::{AppHandle, State};
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::sqlite::tasks::TaskId;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct GetTaskQueueCommandResponse {
|
||||
tasks: Vec<TaskQueueItem>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct TaskQueueItem {
|
||||
pub id: TaskId,
|
||||
pub task_status: TaskStatus,
|
||||
pub task_type: TaskType,
|
||||
pub model_type: Option<TaskModelType>,
|
||||
pub provider: Option<GenerationProvider>,
|
||||
pub provider_job_id: Option<String>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub completed_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
impl SerializeMarker for GetTaskQueueCommandResponse {}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_task_queue_command(
|
||||
app: AppHandle,
|
||||
app_env_configs: State<'_, AppEnvConfigs>,
|
||||
task_database: State<'_, TaskDatabase>,
|
||||
) -> ResponseOrErrorMessage<GetTaskQueueCommandResponse> {
|
||||
|
||||
info!("get_task_queue_command called");
|
||||
|
||||
let result = handle_request(
|
||||
&task_database,
|
||||
).await;
|
||||
|
||||
let tasks = match result {
|
||||
Ok(items) => items,
|
||||
Err(err) => {
|
||||
error!("get_task_queue_command failed: {:?}", err);
|
||||
return Err("get_task_queue_command failed".into())
|
||||
}
|
||||
};
|
||||
|
||||
Ok(GetTaskQueueCommandResponse{
|
||||
tasks,
|
||||
}.into())
|
||||
}
|
||||
|
||||
pub async fn handle_request(
|
||||
task_database: &TaskDatabase,
|
||||
) -> AnyhowResult<Vec<TaskQueueItem>> {
|
||||
|
||||
let tasks = list_tasks_for_frontend(task_database.get_connection())
|
||||
.await?;
|
||||
|
||||
Ok(tasks.tasks.into_iter()
|
||||
.map(|task| TaskQueueItem {
|
||||
id: task.id,
|
||||
task_status: task.status,
|
||||
task_type: task.task_type,
|
||||
model_type: task.model_type,
|
||||
provider: task.provider,
|
||||
provider_job_id: task.provider_job_id,
|
||||
created_at: task.created_at,
|
||||
updated_at: task.updated_at,
|
||||
completed_at: task.completed_at,
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
use crate::core::commands::response::shorthand::ResponseOrErrorMessage;
|
||||
use crate::core::commands::response::success_response_wrapper::SerializeMarker;
|
||||
use crate::core::events::generation_events::generation_enqueue_success_event::GenerationEnqueueSuccessEvent;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
use crate::core::state::data_dir::app_data_root::AppDataRoot;
|
||||
use crate::core::state::provider_priority::{Provider, ProviderPriorityStore};
|
||||
use crate::core::state::task_database::TaskDatabase;
|
||||
use crate::services::fal::state::fal_credential_manager::FalCredentialManager;
|
||||
use crate::services::fal::state::fal_task_queue::FalTaskQueue;
|
||||
use crate::services::sora::state::sora_task_queue::SoraTaskQueue;
|
||||
use crate::services::storyteller::state::storyteller_credential_manager::StorytellerCredentialManager;
|
||||
use chrono::{DateTime, Utc};
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
use enums::tauri::tasks::task_model_type::TaskModelType;
|
||||
use enums::tauri::tasks::task_status::TaskStatus;
|
||||
use enums::tauri::tasks::task_type::TaskType;
|
||||
use errors::AnyhowResult;
|
||||
use log::{error, info, warn};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use sqlite_tasks::queries::list_tasks_for_frontend::list_tasks_for_frontend;
|
||||
use sqlite_tasks::queries::mark_task_as_dismissed::mark_task_as_dismissed;
|
||||
use storyteller_client::endpoints::media_files::delete_media_file::delete_media_file;
|
||||
use tauri::{AppHandle, State};
|
||||
use tokens::tokens::media_files::MediaFileToken;
|
||||
use tokens::tokens::sqlite::tasks::TaskId;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct MarkTaskAsDismissedRequest {
|
||||
task: TaskId,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct MarkTaskAsDismissedResponse {
|
||||
success: bool,
|
||||
}
|
||||
|
||||
impl SerializeMarker for MarkTaskAsDismissedResponse {}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn mark_task_as_dismissed_command(
|
||||
request: MarkTaskAsDismissedRequest,
|
||||
app: AppHandle,
|
||||
app_env_configs: State<'_, AppEnvConfigs>,
|
||||
task_database: State<'_, TaskDatabase>,
|
||||
) -> ResponseOrErrorMessage<MarkTaskAsDismissedResponse> {
|
||||
|
||||
info!("mark_task_as_dismissed_command called");
|
||||
|
||||
let result = handle_request(
|
||||
&request.task,
|
||||
&task_database,
|
||||
).await;
|
||||
|
||||
if let Err(err) = &result {
|
||||
error!("mark_task_as_dismissed_command failed: {:?}", err);
|
||||
return Err("mark_task_as_dismissed_command failed".into())
|
||||
}
|
||||
|
||||
Ok(MarkTaskAsDismissedResponse{
|
||||
success: true,
|
||||
}.into())
|
||||
}
|
||||
|
||||
pub async fn handle_request(
|
||||
task_id: &TaskId,
|
||||
task_database: &TaskDatabase,
|
||||
) -> AnyhowResult<()> {
|
||||
let _result = mark_task_as_dismissed(task_database.get_connection(), task_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod get_task_queue_command;
|
||||
pub mod mark_task_as_dismissed_command;
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::core::state::data_dir::trait_data_subdir::DataSubdir;
|
||||
use crate::core::state::task_database_version::TASK_DATABASE_VERSION;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -24,7 +25,7 @@ impl AppStateDir {
|
||||
pub fn get_tasks_sqlite_database_path(&self) -> PathBuf {
|
||||
// NB: This must be incremented on any change to the database schema (including comments).
|
||||
// The database houses ephemeral content and will be migrated automatically.
|
||||
self.path.join("tasks_v3.sqlite")
|
||||
self.path.join(format!("tasks_v{TASK_DATABASE_VERSION}.sqlite"))
|
||||
}
|
||||
|
||||
pub fn get_window_size_config_file(&self) -> PathBuf {
|
||||
|
||||
@@ -7,4 +7,5 @@ pub mod expanduser;
|
||||
pub mod os_platform;
|
||||
pub mod provider_priority;
|
||||
pub mod task_database;
|
||||
pub mod task_database_version;
|
||||
pub mod window;
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
/// Used to bump the task database schema version.
|
||||
/// Migrations on customers' machines tend to fail on existing databases,
|
||||
/// even if we instruct that the database file be deleted first.
|
||||
/// It's easiest to just write to a new file and migrate from scratch.
|
||||
/// We increment this whenever we make a change to the database schema.
|
||||
/// This prevents deadlock on startup if the schema has changed from the
|
||||
/// previous version.
|
||||
pub const TASK_DATABASE_VERSION: u32 = 4;
|
||||
@@ -18,6 +18,8 @@ use crate::core::commands::media_files::media_file_delete_command::media_file_de
|
||||
use crate::core::commands::platform_info_command::platform_info_command;
|
||||
use crate::core::commands::providers::get_provider_order_command::get_provider_order_command;
|
||||
use crate::core::commands::providers::set_provider_order_command::set_provider_order_command;
|
||||
use crate::core::commands::task_queue::get_task_queue_command::get_task_queue_command;
|
||||
use crate::core::commands::task_queue::mark_task_as_dismissed_command::mark_task_as_dismissed_command;
|
||||
use crate::core::lifecycle::startup::handle_tauri_startup::handle_tauri_startup;
|
||||
use crate::core::lifecycle::startup::setup_main_window::setup_main_window;
|
||||
use crate::core::state::app_env_configs::app_env_configs::AppEnvConfigs;
|
||||
@@ -190,8 +192,10 @@ pub fn run() {
|
||||
get_app_preferences_command,
|
||||
get_fal_api_key_command,
|
||||
get_provider_order_command,
|
||||
media_file_delete_command,
|
||||
get_task_queue_command,
|
||||
load_without_cors_command,
|
||||
mark_task_as_dismissed_command,
|
||||
media_file_delete_command,
|
||||
midjourney_clear_credentials_command,
|
||||
midjourney_get_credential_info_command,
|
||||
midjourney_open_login_command,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use enums::error::enum_error::EnumError;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SqliteTasksError {
|
||||
SqlxError(sqlx::Error),
|
||||
TaskParseError(String),
|
||||
EnumError(EnumError),
|
||||
//TaskNotFound,
|
||||
//TaskAlreadyExists,
|
||||
//InvalidTaskStatus,
|
||||
@@ -17,8 +18,8 @@ impl Error for SqliteTasksError {}
|
||||
impl Display for SqliteTasksError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
SqliteTasksError::SqlxError(err) => write!(f, "SQLx error: {}", err),
|
||||
SqliteTasksError::TaskParseError(err) => write!(f, "Task parse error: {}", err),
|
||||
SqliteTasksError::SqlxError(err) => write!(f, "SQLx error: {:?}", err),
|
||||
SqliteTasksError::EnumError(err) => write!(f, "Error parsing enum: {:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,3 +29,9 @@ impl From<sqlx::Error> for SqliteTasksError {
|
||||
SqliteTasksError::SqlxError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<EnumError> for SqliteTasksError {
|
||||
fn from(err: EnumError) -> Self {
|
||||
SqliteTasksError::EnumError(err)
|
||||
}
|
||||
}
|
||||
|
||||
+5
-10
@@ -92,20 +92,15 @@ pub async fn list_tasks_by_provider_and_status(
|
||||
for task in results {
|
||||
tasks.push(Task {
|
||||
id: TaskId::new_from_str(&task.id),
|
||||
status: TaskStatus::from_str(&task.task_status)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err))?,
|
||||
task_type: TaskType::from_str(&task.task_type)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err))?,
|
||||
status: TaskStatus::from_str(&task.task_status)?,
|
||||
task_type: TaskType::from_str(&task.task_type)?,
|
||||
model_type: task.model_type
|
||||
.map(|model| TaskModelType::from_str(&model)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err)))
|
||||
.map(|model| TaskModelType::from_str(&model))
|
||||
.transpose()?,
|
||||
provider: GenerationProvider::from_str(&task.provider)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err))?,
|
||||
provider: GenerationProvider::from_str(&task.provider)?,
|
||||
provider_job_id: task.provider_job_id,
|
||||
frontend_caller: task.frontend_caller
|
||||
.map(|caller| TauriCommandCaller::from_str(&caller)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err)))
|
||||
.map(|caller| TauriCommandCaller::from_str(&caller))
|
||||
.transpose()?,
|
||||
frontend_subscriber_id: task.frontend_subscriber_id,
|
||||
frontend_subscriber_payload: task.frontend_subscriber_payload,
|
||||
|
||||
+5
-10
@@ -91,20 +91,15 @@ pub async fn list_tasks_by_provider_and_tokens(
|
||||
for task in results {
|
||||
tasks.push(Task {
|
||||
id: TaskId::new_from_str(&task.id),
|
||||
status: TaskStatus::from_str(&task.task_status)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err))?,
|
||||
task_type: TaskType::from_str(&task.task_type)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err))?,
|
||||
status: TaskStatus::from_str(&task.task_status)?,
|
||||
task_type: TaskType::from_str(&task.task_type)?,
|
||||
model_type: task.model_type
|
||||
.map(|model| TaskModelType::from_str(&model)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err)))
|
||||
.map(|model| TaskModelType::from_str(&model))
|
||||
.transpose()?,
|
||||
provider: GenerationProvider::from_str(&task.provider)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err))?,
|
||||
provider: GenerationProvider::from_str(&task.provider)?,
|
||||
provider_job_id: task.provider_job_id,
|
||||
frontend_caller: task.frontend_caller
|
||||
.map(|caller| TauriCommandCaller::from_str(&caller)
|
||||
.map_err(|err| SqliteTasksError::TaskParseError(err)))
|
||||
.map(|caller| TauriCommandCaller::from_str(&caller))
|
||||
.transpose()?,
|
||||
frontend_subscriber_id: task.frontend_subscriber_id,
|
||||
frontend_subscriber_payload: task.frontend_subscriber_payload,
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
use crate::connection::TaskDbConnection;
|
||||
use crate::error::SqliteTasksError;
|
||||
use chrono::{DateTime, Utc};
|
||||
use enums::common::generation_provider::GenerationProvider;
|
||||
use enums::tauri::tasks::task_model_type::TaskModelType;
|
||||
use enums::tauri::tasks::task_status::TaskStatus;
|
||||
use enums::tauri::tasks::task_type::TaskType;
|
||||
use enums::tauri::ux::tauri_command_caller::TauriCommandCaller;
|
||||
use tokens::tokens::sqlite::tasks::TaskId;
|
||||
|
||||
pub struct TaskList {
|
||||
pub tasks: Vec<TaskItem>,
|
||||
}
|
||||
|
||||
pub struct TaskItem {
|
||||
pub id: TaskId,
|
||||
pub status: TaskStatus,
|
||||
pub task_type: TaskType,
|
||||
pub model_type: Option<TaskModelType>,
|
||||
pub provider: Option<GenerationProvider>,
|
||||
pub provider_job_id: Option<String>,
|
||||
pub frontend_caller: Option<TauriCommandCaller>,
|
||||
pub frontend_subscriber_id: Option<String>,
|
||||
pub frontend_subscriber_payload: Option<String>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub completed_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
pub async fn list_tasks_for_frontend(
|
||||
db: & TaskDbConnection
|
||||
) -> Result<TaskList, SqliteTasksError> {
|
||||
let query = sqlx::query_as!(
|
||||
TaskItemRaw,
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
task_status,
|
||||
task_type,
|
||||
model_type,
|
||||
provider,
|
||||
provider_job_id,
|
||||
frontend_caller,
|
||||
frontend_subscriber_id,
|
||||
frontend_subscriber_payload,
|
||||
created_at as "created_at: DateTime<Utc>",
|
||||
updated_at as "updated_at: DateTime<Utc>",
|
||||
completed_at as "completed_at: DateTime<Utc>"
|
||||
FROM tasks
|
||||
WHERE is_dismissed_by_user == 0
|
||||
"#);
|
||||
|
||||
let result = query.fetch_all(db.get_pool())
|
||||
.await?;
|
||||
|
||||
let mut tasks = Vec::with_capacity(result.len());
|
||||
|
||||
for raw in result.into_iter() {
|
||||
tasks.push(TaskItem {
|
||||
id: TaskId::new(raw.id),
|
||||
status: TaskStatus::from_str(&raw.task_status)?,
|
||||
task_type: TaskType::from_str(&raw.task_type)?,
|
||||
model_type: raw.model_type
|
||||
.map(|model| TaskModelType::from_str(&model))
|
||||
.transpose()?,
|
||||
provider: raw.provider
|
||||
.map(|provider| GenerationProvider::from_str(&provider))
|
||||
.transpose()?,
|
||||
provider_job_id: raw.provider_job_id,
|
||||
frontend_caller: raw.frontend_caller
|
||||
.map(|caller| TauriCommandCaller::from_str(&caller))
|
||||
.transpose()?,
|
||||
frontend_subscriber_id: raw.frontend_subscriber_id,
|
||||
frontend_subscriber_payload: raw.frontend_subscriber_payload,
|
||||
created_at: raw.created_at,
|
||||
updated_at: raw.updated_at,
|
||||
completed_at: raw.completed_at,
|
||||
})
|
||||
}
|
||||
|
||||
Ok(TaskList {
|
||||
tasks,
|
||||
})
|
||||
}
|
||||
|
||||
struct TaskItemRaw {
|
||||
id: String,
|
||||
task_status: String,
|
||||
task_type: String,
|
||||
model_type: Option<String>,
|
||||
provider: Option<String>,
|
||||
provider_job_id: Option<String>,
|
||||
frontend_caller: Option<String>,
|
||||
frontend_subscriber_id: Option<String>,
|
||||
frontend_subscriber_payload: Option<String>,
|
||||
created_at: DateTime<Utc>,
|
||||
updated_at: DateTime<Utc>,
|
||||
completed_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
use crate::connection::TaskDbConnection;
|
||||
use crate::error::SqliteTasksError;
|
||||
use tokens::tokens::sqlite::tasks::TaskId;
|
||||
|
||||
/// Returns true if rows were updated.
|
||||
pub async fn mark_task_as_dismissed(
|
||||
db: &TaskDbConnection,
|
||||
task_id: &TaskId,
|
||||
) -> Result<bool, SqliteTasksError> {
|
||||
|
||||
// TODO(bt,2025-07-12): Fix this. The sqlx mysql queries never required temporaries
|
||||
let task_id_temp = task_id.as_str();
|
||||
|
||||
// TODO(bt,2025-07-15): We can't set a LIMIT without a certain compiler flag for SQLite ?
|
||||
let query = sqlx::query!(r#"
|
||||
UPDATE tasks
|
||||
SET is_dismissed_by_user = 1
|
||||
WHERE id = ?
|
||||
"#,
|
||||
task_id_temp,
|
||||
);
|
||||
|
||||
let res = query.execute(db.get_pool()).await?;
|
||||
let rows_updated = res.rows_affected() > 0;
|
||||
|
||||
Ok(rows_updated)
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
pub mod create_task;
|
||||
pub mod list_tasks_by_provider_and_status;
|
||||
pub mod list_tasks_by_provider_and_tokens;
|
||||
pub mod list_tasks_for_frontend;
|
||||
pub mod mark_task_as_dismissed;
|
||||
pub mod update_task_status;
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::error::enum_error::EnumError;
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
@@ -22,6 +23,9 @@ impl_enum_display_and_debug_using_to_str!(GenerationProvider);
|
||||
impl_mysql_enum_coders!(GenerationProvider);
|
||||
impl_mysql_from_row!(GenerationProvider);
|
||||
|
||||
// For Tauri
|
||||
impl_sqlite_enum_coders!(GenerationProvider);
|
||||
|
||||
// NB: We can derive `sqlx::Type` instead of using `impl_mysql_enum_coders`
|
||||
|
||||
impl GenerationProvider {
|
||||
@@ -34,13 +38,13 @@ impl GenerationProvider {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(job_status: &str) -> Result<Self, String> {
|
||||
match job_status {
|
||||
pub fn from_str(value: &str) -> Result<Self, EnumError> {
|
||||
match value {
|
||||
"artcraft" => Ok(Self::Artcraft),
|
||||
"fal" => Ok(Self::Fal),
|
||||
"midjourney" => Ok(Self::Midjourney),
|
||||
"sora" => Ok(Self::Sora),
|
||||
_ => Err(format!("invalid generation_provider: {:?}", job_status)),
|
||||
_ => Err(EnumError::CouldNotConvertFromString(value.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +62,9 @@ impl GenerationProvider {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test_helpers::assert_serialization;
|
||||
use crate::common::generation_provider::GenerationProvider;
|
||||
use crate::error::enum_error::EnumError;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
mod explicit_checks {
|
||||
use super::*;
|
||||
@@ -88,6 +93,17 @@ mod tests {
|
||||
assert_eq!(GenerationProvider::from_str("sora").unwrap(), GenerationProvider::Sora);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str_err() {
|
||||
let result = GenerationProvider::from_str("asdf");
|
||||
assert!(result.is_err());
|
||||
if let Err(EnumError::CouldNotConvertFromString(value)) = result {
|
||||
assert_eq!(value, "asdf");
|
||||
} else {
|
||||
panic!("Expected EnumError::CouldNotConvertFromString");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = GenerationProvider::all_variants();
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EnumError {
|
||||
CouldNotConvertFromString(String),
|
||||
}
|
||||
|
||||
impl Error for EnumError {}
|
||||
|
||||
impl std::fmt::Display for EnumError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
EnumError::CouldNotConvertFromString(value) => {
|
||||
write!(f, "Could not convert from string: {}", value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod enum_error;
|
||||
@@ -33,6 +33,7 @@ mod macros;
|
||||
|
||||
pub mod by_table;
|
||||
pub mod common;
|
||||
pub mod error;
|
||||
pub mod no_table;
|
||||
pub mod tauri;
|
||||
pub mod traits;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::error::enum_error::EnumError;
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
@@ -98,8 +99,8 @@ impl TaskModelType {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(job_status: &str) -> Result<Self, String> {
|
||||
match job_status {
|
||||
pub fn from_str(value: &str) -> Result<Self, EnumError> {
|
||||
match value {
|
||||
// Image models
|
||||
"flux_1_dev" => Ok(Self::Flux1Dev),
|
||||
"flux_1_schnell" => Ok(Self::Flux1Schnell),
|
||||
@@ -124,7 +125,7 @@ impl TaskModelType {
|
||||
// 3D Object generation models
|
||||
"hunyuan_3d_2.0" => Ok(Self::Hunyuan3d2_0),
|
||||
"hunyuan_3d_2.1" => Ok(Self::Hunyuan3d2_1),
|
||||
_ => Err(format!("invalid task_model_type: {:?}", job_status)),
|
||||
_ => Err(EnumError::CouldNotConvertFromString(value.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +165,7 @@ impl TaskModelType {
|
||||
mod tests {
|
||||
use crate::tauri::tasks::task_model_type::TaskModelType;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
use crate::error::enum_error::EnumError;
|
||||
|
||||
mod explicit_checks {
|
||||
use super::*;
|
||||
@@ -252,6 +254,17 @@ mod tests {
|
||||
assert_eq!(TaskModelType::from_str("hunyuan_3d_2.1").unwrap(), TaskModelType::Hunyuan3d2_1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str_err() {
|
||||
let result = TaskModelType::from_str("asdf");
|
||||
assert!(result.is_err());
|
||||
if let Err(EnumError::CouldNotConvertFromString(value)) = result {
|
||||
assert_eq!(value, "asdf");
|
||||
} else {
|
||||
panic!("Expected EnumError::CouldNotConvertFromString");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = TaskModelType::all_variants();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::error::enum_error::EnumError;
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
@@ -48,8 +49,8 @@ impl TaskStatus {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(job_status: &str) -> Result<Self, String> {
|
||||
match job_status {
|
||||
pub fn from_str(value: &str) -> Result<Self, EnumError> {
|
||||
match value {
|
||||
"pending" => Ok(Self::Pending),
|
||||
"started" => Ok(Self::Started),
|
||||
"complete_success" => Ok(Self::CompleteSuccess),
|
||||
@@ -59,7 +60,7 @@ impl TaskStatus {
|
||||
"cancelled_by_user" => Ok(Self::CancelledByUser),
|
||||
"cancelled_by_provider" => Ok(Self::CancelledByProvider),
|
||||
"cancelled_by_us" => Ok(Self::CancelledByUs),
|
||||
_ => Err(format!("invalid task_status: {:?}", job_status)),
|
||||
_ => Err(EnumError::CouldNotConvertFromString(value.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,11 +83,12 @@ impl TaskStatus {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test_helpers::assert_serialization;
|
||||
use crate::tauri::tasks::task_status::TaskStatus;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
mod explicit_checks {
|
||||
use super::*;
|
||||
use crate::error::enum_error::EnumError;
|
||||
|
||||
#[test]
|
||||
fn test_default() {
|
||||
@@ -132,6 +134,17 @@ mod tests {
|
||||
assert_eq!(TaskStatus::from_str("cancelled_by_us").unwrap(), TaskStatus::CancelledByUs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str_err() {
|
||||
let result = TaskStatus::from_str("asdf");
|
||||
assert!(result.is_err());
|
||||
if let Err(EnumError::CouldNotConvertFromString(value)) = result {
|
||||
assert_eq!(value, "asdf");
|
||||
} else {
|
||||
panic!("Expected EnumError::CouldNotConvertFromString");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = TaskStatus::all_variants();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::error::enum_error::EnumError;
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
@@ -34,14 +35,14 @@ impl TaskType {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(job_status: &str) -> Result<Self, String> {
|
||||
match job_status {
|
||||
pub fn from_str(value: &str) -> Result<Self, EnumError> {
|
||||
match value {
|
||||
"image_generation" => Ok(Self::ImageGeneration),
|
||||
"image_inpaint_edit" => Ok(Self::ImageInpaintEdit),
|
||||
"video_generation" => Ok(Self::VideoGeneration),
|
||||
"object_generation" => Ok(Self::ObjectGeneration),
|
||||
"background_removal" => Ok(Self::BackgroundRemoval),
|
||||
_ => Err(format!("invalid task_type: {:?}", job_status)),
|
||||
_ => Err(EnumError::CouldNotConvertFromString(value.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,11 +61,12 @@ impl TaskType {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test_helpers::assert_serialization;
|
||||
use crate::tauri::tasks::task_type::TaskType;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
mod explicit_checks {
|
||||
use super::*;
|
||||
use crate::error::enum_error::EnumError;
|
||||
|
||||
#[test]
|
||||
fn test_serialization() {
|
||||
@@ -92,6 +94,17 @@ mod tests {
|
||||
assert_eq!(TaskType::from_str("object_generation").unwrap(), TaskType::ObjectGeneration);
|
||||
assert_eq!(TaskType::from_str("background_removal").unwrap(), TaskType::BackgroundRemoval);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str_err() {
|
||||
let result = TaskType::from_str("asdf");
|
||||
assert!(result.is_err());
|
||||
if let Err(EnumError::CouldNotConvertFromString(value)) = result {
|
||||
assert_eq!(value, "asdf");
|
||||
} else {
|
||||
panic!("Expected EnumError::CouldNotConvertFromString");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::error::enum_error::EnumError;
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
#[cfg(test)]
|
||||
@@ -38,13 +39,13 @@ impl TauriCommandCaller {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(job_status: &str) -> Result<Self, String> {
|
||||
match job_status {
|
||||
pub fn from_str(value: &str) -> Result<Self, EnumError> {
|
||||
match value {
|
||||
"canvas" => Ok(Self::Canvas),
|
||||
"image_editor" => Ok(Self::ImageEditor),
|
||||
"text_to_image" => Ok(Self::TextToImage),
|
||||
"image_to_video" => Ok(Self::ImageToVideo),
|
||||
_ => Err(format!("invalid tauri_command_caller: {:?}", job_status)),
|
||||
_ => Err(EnumError::CouldNotConvertFromString(value.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,8 +63,9 @@ impl TauriCommandCaller {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test_helpers::assert_serialization;
|
||||
use crate::error::enum_error::EnumError;
|
||||
use crate::tauri::ux::tauri_command_caller::TauriCommandCaller;
|
||||
use crate::test_helpers::assert_serialization;
|
||||
|
||||
mod explicit_checks {
|
||||
use super::*;
|
||||
@@ -92,6 +94,17 @@ mod tests {
|
||||
assert_eq!(TauriCommandCaller::from_str("image_to_video").unwrap(), TauriCommandCaller::ImageToVideo);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_str_err() {
|
||||
let result = TauriCommandCaller::from_str("asdf");
|
||||
assert!(result.is_err());
|
||||
if let Err(EnumError::CouldNotConvertFromString(value)) = result {
|
||||
assert_eq!(value, "asdf");
|
||||
} else {
|
||||
panic!("Expected EnumError::CouldNotConvertFromString");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_variants() {
|
||||
let mut variants = TauriCommandCaller::all_variants();
|
||||
|
||||
@@ -156,6 +156,9 @@
|
||||
},
|
||||
{
|
||||
"path": "../../libs/api"
|
||||
},
|
||||
{
|
||||
"path": "../../libs/api-enums"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../.eslintrc.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.json"
|
||||
],
|
||||
"parser": "jsonc-eslint-parser",
|
||||
"rules": {
|
||||
"@nx/dependency-checks": [
|
||||
"error",
|
||||
{
|
||||
"ignoredFiles": [
|
||||
"{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}",
|
||||
"{projectRoot}/vite.config.{js,ts,mjs,mts}"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# api-enums
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build api-enums` to build the library.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test api-enums` to execute the unit tests via [Vitest](https://vitest.dev/).
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@storyteller/api-enums",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './lib/index.js';
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
// NOTE: These are defined in Rust (as the source of truth) and duplicated in the frontend.
|
||||
// In the future, we should use code gen (protobufs or similar) to keep the two sides in sync.
|
||||
|
||||
export enum GenerationProvider {
|
||||
Artcraft = "artcraft",
|
||||
Fal = "fal",
|
||||
Midjourney = "midjourney",
|
||||
Sora = "sora",
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./generation_provider.js";
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./common/index.js";
|
||||
export * from "./tauri/index.js";
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./tasks/index.js";
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./task_model_type.js";
|
||||
export * from "./task_status.js";
|
||||
export * from "./task_type.js";
|
||||
@@ -0,0 +1,33 @@
|
||||
// NOTE: These are defined in Rust (as the source of truth) and duplicated in the frontend.
|
||||
// In the future, we should use code gen (protobufs or similar) to keep the two sides in sync.
|
||||
|
||||
export enum TaskModelType {
|
||||
// Image models
|
||||
Flux1Dev = "flux_1_dev",
|
||||
Flux1Schnell = "flux_1_schnell",
|
||||
FluxDevJuggernaut = "flux_dev_juggernaut",
|
||||
FluxPro1 = "flux_pro_1",
|
||||
FluxPro11 = "flux_pro_1.1",
|
||||
FluxPro11Ultra = "flux_pro_1.1_ultra",
|
||||
FluxProKontextMax = "flux_pro_kontext_max",
|
||||
Gemini25Flash = "gemini_25_flash",
|
||||
GptImage1 = "gpt_image_1",
|
||||
Recraft3 = "recraft_3",
|
||||
|
||||
// Generic Midjourney model, version unknown.
|
||||
Midjourney = "midjourney",
|
||||
|
||||
// Video models
|
||||
Kling16Pro = "kling_1.6_pro",
|
||||
Kling21Pro = "kling_2.1_pro",
|
||||
Kling21Master = "kling_2.1_master",
|
||||
Seedance10Lite = "seedance_1.0_lite",
|
||||
Sora2 = "sora_2",
|
||||
Veo2 = "veo_2",
|
||||
Veo3 = "veo_3",
|
||||
Veo3Fast = "veo_3_fast",
|
||||
|
||||
// 3D Object generation models
|
||||
Hunyuan3d2_0 = "hunyuan_3d_2.0",
|
||||
Hunyuan3d2_1 = "hunyuan_3d_2.1",
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// NOTE: These are defined in Rust (as the source of truth) and duplicated in the frontend.
|
||||
// In the future, we should use code gen (protobufs or similar) to keep the two sides in sync.
|
||||
|
||||
export enum TaskStatus {
|
||||
Pending = "pending",
|
||||
Started = "started",
|
||||
CompleteSuccess = "complete_success",
|
||||
CompleteFailure = "complete_failure",
|
||||
AttemptFailed = "attempt_failed",
|
||||
Dead = "dead",
|
||||
CancelledByUser = "cancelled_by_user",
|
||||
CancelledByProvider = "cancelled_by_provider",
|
||||
CancelledByUs = "cancelled_by_us",
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// NOTE: These are defined in Rust (as the source of truth) and duplicated in the frontend.
|
||||
// In the future, we should use code gen (protobufs or similar) to keep the two sides in sync.
|
||||
|
||||
export enum TaskType {
|
||||
ImageGeneration = "image_generation",
|
||||
ImageInpaintEdit = "image_inpaint_edit",
|
||||
VideoGeneration = "video_generation",
|
||||
ObjectGeneration = "object_generation",
|
||||
BackgroundRemoval = "background_removal",
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"rootDir": "src",
|
||||
"outDir": "dist",
|
||||
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
|
||||
"emitDeclarationOnly": true,
|
||||
"module": "nodenext",
|
||||
"moduleResolution": "nodenext",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"types": [
|
||||
"node",
|
||||
"vite/client"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"references": [],
|
||||
"exclude": [
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/vitest",
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
"vitest/importMeta",
|
||||
"vite/client",
|
||||
"node",
|
||||
"vitest"
|
||||
],
|
||||
"module": "nodenext",
|
||||
"moduleResolution": "nodenext",
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
import dts from 'vite-plugin-dts';
|
||||
import * as path from 'path';
|
||||
|
||||
export default defineConfig(() => ({
|
||||
root: __dirname,
|
||||
cacheDir: '../../node_modules/.vite/libs/api-enums',
|
||||
plugins: [dts({ entryRoot: 'src', tsconfigPath: path.join(__dirname, 'tsconfig.lib.json') })],
|
||||
// Uncomment this if you are using workers.
|
||||
// worker: {
|
||||
// plugins: [ nxViteTsPaths() ],
|
||||
// },
|
||||
// Configuration for building your library.
|
||||
// See: https://vitejs.dev/guide/build.html#library-mode
|
||||
build: {
|
||||
outDir: './dist',
|
||||
emptyOutDir: true,
|
||||
reportCompressedSize: true,
|
||||
commonjsOptions: {
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
lib: {
|
||||
// Could also be a dictionary or array of multiple entry points.
|
||||
entry: 'src/index.ts',
|
||||
name: '@storyteller/api-enums',
|
||||
fileName: 'index',
|
||||
// Change this to the formats you want to support.
|
||||
// Don't forget to update your package.json as well.
|
||||
formats: ['es' as const]
|
||||
},
|
||||
rollupOptions: {
|
||||
// External packages that should not be bundled into your library.
|
||||
external: []
|
||||
},
|
||||
},
|
||||
test: {
|
||||
watch: false,
|
||||
globals: true,
|
||||
environment: 'node',
|
||||
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
reporters: ['default'],
|
||||
coverage: {
|
||||
reportsDirectory: './test-output/vitest/coverage',
|
||||
provider: 'v8' as const,
|
||||
}
|
||||
},
|
||||
}));
|
||||
@@ -6,6 +6,9 @@
|
||||
{
|
||||
"path": "../tauri-utils"
|
||||
},
|
||||
{
|
||||
"path": "../api-enums"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
"references": [
|
||||
{
|
||||
"path": "../tauri-utils/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../api-enums/tsconfig.lib.json"
|
||||
}
|
||||
],
|
||||
"exclude": [
|
||||
|
||||
@@ -20,6 +20,7 @@ export * from "./lib/openai/GetOpenAIApiKey.js";
|
||||
export * from "./lib/openai/SetOpenAIApiKey.js";
|
||||
export * from "./lib/providers/GetProviderOrder.js";
|
||||
export * from "./lib/providers/Provider.js";
|
||||
export * from "./lib/artcraft/task_queue/GetTaskQueue.js";
|
||||
export * from "./lib/providers/SetProviderOrder.js";
|
||||
export * from "./lib/settings/GetAppPreferences.js";
|
||||
export * from "./lib/settings/UpdateAppPreference.js";
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../../common/CommandStatus";
|
||||
import { TaskStatus, TaskType, TaskModelType, GenerationProvider } from "@storyteller/api-enums";
|
||||
|
||||
interface GetTaskQueueResponse {
|
||||
tasks: TaskQueueItem[],
|
||||
}
|
||||
|
||||
export interface TaskQueueItem {
|
||||
id: string,
|
||||
task_status: TaskStatus,
|
||||
task_type: TaskType,
|
||||
model_type?: TaskModelType,
|
||||
provider?: GenerationProvider,
|
||||
provider_job_id?: string,
|
||||
created_at: Date,
|
||||
updated_at: Date,
|
||||
completed_at?: Date,
|
||||
}
|
||||
|
||||
interface GetTaskQueueSuccess extends CommandResult {
|
||||
payload: GetTaskQueueResponse;
|
||||
}
|
||||
|
||||
export const GetTaskQueue = async () : Promise<GetTaskQueueResponse> => {
|
||||
try {
|
||||
let result = await invoke("get_task_queue_command") as GetTaskQueueSuccess;
|
||||
return result.payload;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
(window as any).test_get_task_queue = GetTaskQueue;
|
||||
@@ -0,0 +1,22 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { CommandResult } from "../../common/CommandStatus";
|
||||
|
||||
interface MarkTaskAsDismissedSuccess extends CommandResult {
|
||||
payload: void;
|
||||
}
|
||||
|
||||
export const MarkTaskAsDismissed = async (task_id: string) : Promise<MarkTaskAsDismissedSuccess> => {
|
||||
try {
|
||||
let result = await invoke("mark_task_as_dismissed_command", {
|
||||
request: {
|
||||
task: task_id
|
||||
}
|
||||
}) as MarkTaskAsDismissedSuccess;
|
||||
return result;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Temporary just for testing -
|
||||
(window as any).test_mark_task_as_dismissed = MarkTaskAsDismissed;
|
||||
@@ -10,6 +10,9 @@
|
||||
},
|
||||
{
|
||||
"path": "../model-list"
|
||||
},
|
||||
{
|
||||
"path": "../api-enums"
|
||||
}
|
||||
],
|
||||
"extends": "../../tsconfig.base.json"
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
"references": [
|
||||
{
|
||||
"path": "../model-list/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../api-enums/tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Generated
+345
-166
File diff suppressed because it is too large
Load Diff
@@ -170,6 +170,9 @@
|
||||
},
|
||||
{
|
||||
"path": "./libs/components/tutorial-modal"
|
||||
},
|
||||
{
|
||||
"path": "./libs/api-enums"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user