Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0af394c
refactor(app-lib): use state helpers instead of raw state
Sychic Oct 6, 2026
39530e0
fix(app-lib): await state instead of polling
Sychic Oct 6, 2026
41d2007
refactor(app-lib): get state outside jre helper
Sychic Oct 7, 2026
a41b4f9
refactor(app-lib): get state outside file fetching
Sychic Oct 8, 2026
55d6665
refactor(app-lib): pull state out of edit_instance
Sychic Oct 8, 2026
a7bb3fb
refactor(app-lib): pull state out of discord stuff
Sychic Oct 8, 2026
4a1e641
refactor(app-lib): pull state out of file watcher
Sychic Oct 8, 2026
034271c
refactor(app-lib): pass sqlite pool instead of whole state and retain…
Sychic Oct 8, 2026
7d5c866
refactor(app-lib): pass state directly to install functions
Sychic Oct 8, 2026
033cb4c
refactor(app-lib): pass state to clear_staging_dir
Sychic Oct 8, 2026
c91d9f2
refactor(app-lib): pass state to runner jobs
Sychic Oct 8, 2026
91b12f4
refactor(app-lib): lift state access out of mc install functions
Sychic Oct 8, 2026
438dac0
refactor(app-lib): lift state access out of mc launch functions
Sychic Oct 8, 2026
7119e70
refactor(app-lib): lift state access out of mc loader functions
Sychic Oct 8, 2026
c943f91
refactor(app-lib): lift state access out of launch_mc
Sychic Oct 8, 2026
4c40721
refactor(app-lib): lift state access out of wait for job
Sychic Oct 8, 2026
13f5efe
refactor(app-lib): lift state access out of state functions
Sychic Oct 8, 2026
46d8d87
refactor(app-lib): lift state access out of logging
Sychic Oct 8, 2026
4e79392
refactor(app-lib): only pass pool to get java version
Sychic Oct 8, 2026
acb28bb
refactor(app-lib): only pass directory info to get loader
Sychic Oct 8, 2026
b1fbdc5
refactor(app-lib): only pass directory info to get instance full path
Sychic Oct 8, 2026
90ec70c
refactor(app-lib): only pass pool to install_pack
Sychic Oct 8, 2026
31375ab
refactor(app-lib): only pass content store to clear_staging_dir
Sychic Oct 8, 2026
ee39d35
refactor(app-lib): only pass pool to update_playtime
Sychic Oct 8, 2026
f771fb5
refactor(app-lib): only pass pool to watcher
Sychic Oct 8, 2026
cf7d1b7
style(app-lib): fmt
Sychic Oct 8, 2026
affccce
refactor(app-lib): remove extra state get
Sychic Oct 8, 2026
4033552
refactor(app-lib): only pass pool to clear_persisted_process
Sychic Oct 8, 2026
16f9be0
refactor(app-lib): pull out install concurrency
Sychic Oct 9, 2026
5101d51
refactor(app-lib): pull out social stuff
Sychic Oct 9, 2026
6feda8b
refactor(app-lib): pull out per-instance concurrency
Sychic Oct 9, 2026
5fd1322
refactor(app-lib): pull out options syncing concurrency
Sychic Oct 9, 2026
928759c
refactor(app-lib): narrow state params to instance locks
Sychic Oct 9, 2026
dc5b6de
refactor(app-lib): narrow state params to directory info
Sychic Oct 9, 2026
0507142
refactor(app-lib): narrow state params to pool
Sychic Oct 9, 2026
4509776
refactor(app-lib): narrow state params to api semaphore
Sychic Oct 9, 2026
4d91ac6
refactor(app-lib): narrow state params to io semaphore
Sychic Oct 9, 2026
30a0933
refactor(app-lib): narrow state params to content store
Sychic Oct 9, 2026
c708e30
Merge remote-tracking branch 'origin/main' into sychic/app-state-get-…
Sychic Oct 19, 2026
769dd88
Merge branch 'sychic/app-state-get-cleanup' into sychic/decompose-app…
Sychic Oct 19, 2026
1e71e9c
Merge remote-tracking branch 'origin/main' into sychic/decompose-app-…
Sychic Oct 19, 2026
0a22560
Merge of #7919
mergify[bot] Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/app-lib/src/api/friends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub async fn friends() -> crate::Result<Vec<UserFriend>> {

pub async fn friend_statuses() -> crate::Result<Vec<UserStatus>> {
let state = crate::State::get().await?;
let statuses = state.friends_socket.friend_statuses();
let statuses = state.presence.friends_socket.friend_statuses();

Ok(statuses)
}
Expand Down
8 changes: 4 additions & 4 deletions packages/app-lib/src/api/instance/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub async fn write_instance_file(
create_only: bool,
) -> crate::Result<()> {
let state = State::get().await?;
let _instance = state.lock_instance_content(instance_id).await;
let _instance = state.instance_locks.lock_content(instance_id).await;
let _files = state.content_store.files_lock.lock().await;
let destination = resolve(&state, instance_id, path, true)
.await?
Expand Down Expand Up @@ -238,7 +238,7 @@ pub async fn create_instance_directory(
path: &str,
) -> crate::Result<()> {
let state = State::get().await?;
let _instance = state.lock_instance_content(instance_id).await;
let _instance = state.instance_locks.lock_content(instance_id).await;
let _files = state.content_store.files_lock.lock().await;
let destination = resolve(&state, instance_id, path, true).await?;
fs::create_dir(destination.path()).await?;
Expand All @@ -251,7 +251,7 @@ pub async fn rename_instance_file(
destination: &str,
) -> crate::Result<()> {
let state = State::get().await?;
let _instance = state.lock_instance_content(instance_id).await;
let _instance = state.instance_locks.lock_content(instance_id).await;
let _files = state.content_store.files_lock.lock().await;
let source = resolve(&state, instance_id, source, true).await?;
let destination = resolve(&state, instance_id, destination, true).await?;
Expand All @@ -270,7 +270,7 @@ pub async fn delete_instance_file(
recursive: bool,
) -> crate::Result<()> {
let state = State::get().await?;
let _instance = state.lock_instance_content(instance_id).await;
let _instance = state.instance_locks.lock_content(instance_id).await;
let _files = state.content_store.files_lock.lock().await;
let path = resolve(&state, instance_id, path, true).await?;
if fs::symlink_metadata(path.path()).await?.is_dir() {
Expand Down
30 changes: 18 additions & 12 deletions packages/app-lib/src/api/instance/screenshots/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::state::instances::adapters::sqlite::{
instance_rows::{self, InstanceScreenshotSource},
screenshot_rows,
};
use crate::state::{DirectoryInfo, InstanceLocks};
use crate::util::fetch::sha1_file_async;
use crate::util::io::{self, IOError};
use crate::{ErrorKind, State};
Expand Down Expand Up @@ -103,12 +104,12 @@ async fn list_source_screenshot_sets(
}

async fn lock_instance_screenshots<'a>(
state: &State,
instance_locks: &InstanceLocks,
instance_ids: impl IntoIterator<Item = &'a str>,
) -> Vec<OwnedMutexGuard<()>> {
let mut locks = Vec::new();
for instance_id in instance_ids {
locks.push(state.lock_instance_screenshots(instance_id).await);
locks.push(instance_locks.lock_screenshots(instance_id).await);
}
locks
}
Expand All @@ -122,7 +123,8 @@ pub async fn delete_screenshots(keys: &[ScreenshotKey]) -> crate::Result<()> {
.collect::<Vec<_>>();
instance_ids.sort_unstable();
instance_ids.dedup();
let _locks = lock_instance_screenshots(&state, instance_ids).await;
let _locks =
lock_instance_screenshots(&state.instance_locks, instance_ids).await;

for key in keys {
io::remove_file(get_screenshot_path(key).await?).await?;
Expand Down Expand Up @@ -224,14 +226,16 @@ pub async fn move_screenshots(
.collect::<Vec<_>>();
instance_ids.sort_unstable();
instance_ids.dedup();
let _locks = lock_instance_screenshots(&state, instance_ids).await;
let _locks =
lock_instance_screenshots(&state.instance_locks, instance_ids).await;
let target_source = instance_rows::get_instance_screenshot_source(
target_instance_id,
&state.pool,
)
.await?
.ok_or(ErrorKind::InputError("unknown target instance".to_string()))?;
let target_dir = source_screenshots_dir(&state, &target_source).await?;
let target_dir =
source_screenshots_dir(&state.directories, &target_source).await?;
io::create_dir_all(&target_dir).await?;
ensure_directory_is_not_symlink(&target_dir).await?;

Expand Down Expand Up @@ -285,7 +289,8 @@ pub async fn get_screenshot_path(
)
.await?
.ok_or(ErrorKind::InputError("unknown instance".to_string()))?;
let screenshots_dir = source_screenshots_dir(&state, &source).await?;
let screenshots_dir =
source_screenshots_dir(&state.directories, &source).await?;
let canonical_dir = tokio::fs::canonicalize(&screenshots_dir)
.await
.map_err(|error| IOError::with_path(error, &screenshots_dir))?;
Expand Down Expand Up @@ -327,9 +332,9 @@ pub async fn save_edited_screenshot(
)
.await?
.ok_or(ErrorKind::InputError("unknown instance".to_string()))?;
let _lock = state.lock_instance_screenshots(&source.id).await;
let _lock = state.instance_locks.lock_screenshots(&source.id).await;

let scanned = scan_source_screenshots(&state, &source).await?;
let scanned = scan_source_screenshots(&state.directories, &source).await?;
let current =
reconcile_source_screenshots(&state, &source, scanned).await?;
let source_screenshot = current
Expand Down Expand Up @@ -374,7 +379,8 @@ pub async fn save_edited_screenshot(
)));
}

let screenshots_dir = source_screenshots_dir(&state, &source).await?;
let screenshots_dir =
source_screenshots_dir(&state.directories, &source).await?;
let (target_path, copy_group) = match mode {
ScreenshotEditSaveMode::CreateCopy => (
available_target_path(&screenshots_dir, &source_row.file_name)
Expand Down Expand Up @@ -407,7 +413,7 @@ pub async fn save_edited_screenshot(
screenshot_rows::update_screenshot(&source_row, &mut tx).await?;
tx.commit().await?;
}
let scanned = scan_source_screenshots(&state, &source).await?;
let scanned = scan_source_screenshots(&state.directories, &source).await?;
let reconciled =
reconcile_source_screenshots(&state, &source, scanned).await?;
let mut saved = reconciled
Expand Down Expand Up @@ -478,10 +484,10 @@ pub async fn save_edited_screenshot(
}

pub(super) async fn source_screenshots_dir(
state: &State,
directories: &DirectoryInfo,
source: &InstanceScreenshotSource,
) -> crate::Result<PathBuf> {
let instance_dir = state.directories.instances_dir().join(&source.path);
let instance_dir = directories.instances_dir().join(&source.path);
let canonical_instance_dir =
tokio::fs::canonicalize(&instance_dir)
.await
Expand Down
11 changes: 6 additions & 5 deletions packages/app-lib/src/api/instance/screenshots/reconciliation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::operations::{
InstanceScreenshot, has_png_extension, sort_screenshots,
source_screenshots_dir,
};
use crate::state::DirectoryInfo;
use crate::state::instances::adapters::sqlite::{
instance_rows::{self, InstanceScreenshotSource},
screenshot_rows::{self, ScreenshotRow},
Expand Down Expand Up @@ -80,8 +81,8 @@ pub(super) async fn list_source_screenshots(
state: &State,
source: InstanceScreenshotSource,
) -> crate::Result<Vec<InstanceScreenshot>> {
let _lock = state.lock_instance_screenshots(&source.id).await;
let scanned = scan_source_screenshots(state, &source).await?;
let _lock = state.instance_locks.lock_screenshots(&source.id).await;
let scanned = scan_source_screenshots(&state.directories, &source).await?;
reconcile_source_screenshots(state, &source, scanned).await
}

Expand All @@ -101,18 +102,18 @@ pub(crate) async fn reconcile_screenshots(
}

pub(super) async fn scan_source_screenshots(
state: &State,
directories: &DirectoryInfo,
source: &InstanceScreenshotSource,
) -> crate::Result<Vec<ScannedScreenshot>> {
let instance_dir = state.directories.instances_dir().join(&source.path);
let instance_dir = directories.instances_dir().join(&source.path);
if !tokio::fs::try_exists(&instance_dir)
.await
.map_err(|error| IOError::with_path(error, &instance_dir))?
{
return Ok(Vec::new());
}

let screenshots_dir = source_screenshots_dir(state, source).await?;
let screenshots_dir = source_screenshots_dir(directories, source).await?;
tokio::task::spawn_blocking(move || scan_screenshots_dir(&screenshots_dir))
.await?
}
Expand Down
12 changes: 8 additions & 4 deletions packages/app-lib/src/api/instance/shared/invites.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ pub async fn invite_shared_instance_users(
user_ids: Vec<String>,
) -> crate::Result<SharedInstanceUsers> {
let state = State::get().await?;
let _shared_instance_lock = state.lock_shared_instance(instance_id).await;
let _shared_instance_lock =
state.instance_locks.lock_shared(instance_id).await;
let (metadata, attachment) =
shared_instance_for_invites(instance_id, user_ids.len(), &state)
.await?;
Expand Down Expand Up @@ -65,7 +66,8 @@ pub async fn create_shared_instance_invite_link(
replace_invite_id: Option<String>,
) -> crate::Result<SharedInstanceInviteLink> {
let state = State::get().await?;
let _shared_instance_lock = state.lock_shared_instance(instance_id).await;
let _shared_instance_lock =
state.instance_locks.lock_shared(instance_id).await;
let (metadata, attachment) =
shared_instance_for_invites(instance_id, 0, &state).await?;
ensure_owner(&attachment)?;
Expand Down Expand Up @@ -150,7 +152,8 @@ pub async fn revoke_shared_instance_invite(
invite_id: String,
) -> crate::Result<()> {
let state = State::get().await?;
let _shared_instance_lock = state.lock_shared_instance(instance_id).await;
let _shared_instance_lock =
state.instance_locks.lock_shared(instance_id).await;
let Some(attachment) = shared_attachment(instance_id, &state).await? else {
return Ok(());
};
Expand All @@ -167,7 +170,8 @@ pub async fn remove_shared_instance_users(
has_pending_recipients: bool,
) -> crate::Result<SharedInstanceUsers> {
let state = State::get().await?;
let _shared_instance_lock = state.lock_shared_instance(instance_id).await;
let _shared_instance_lock =
state.instance_locks.lock_shared(instance_id).await;
let Some(attachment) = shared_attachment(instance_id, &state).await? else {
return Ok(SharedInstanceUsers::empty());
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const COMMAND_HISTORY_LIMIT: usize = 50;

pub async fn get_command_history() -> crate::Result<String> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
let path = command_history_path(&state);
if !path.exists() {
return Ok(String::new());
Expand All @@ -25,7 +25,7 @@ pub async fn get_command_history() -> crate::Result<String> {

pub async fn set_command_history(contents: &str) -> crate::Result<String> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
create_synced_directories(&state).await?;
let normalized = normalize_command_history(contents);
io::write(command_history_path(&state), normalized.as_bytes()).await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(super) fn currently_launcher_owned_keys(
/// Writes canonical settings to `options.txt` before launch.
pub async fn sync_before_launch(instance_id: &str) -> crate::Result<()> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
let metadata = crate::state::get_instance(instance_id, &state.pool)
.await?
.ok_or(ErrorKind::InputError("unknown instance".to_string()))?;
Expand All @@ -48,7 +48,7 @@ pub async fn apply_launcher_overrides(
return Ok(());
}
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
let metadata = crate::state::get_instance(instance_id, &state.pool)
.await?
.ok_or(ErrorKind::InputError("unknown instance".to_string()))?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ pub async fn get_config(
instance_id: &str,
) -> crate::Result<GameSettingsEditorState> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
load_editor(instance_id, &state).await
}

Expand All @@ -275,7 +275,7 @@ pub async fn preview_changes(
request: UpdateGameSettingsRequest,
) -> crate::Result<GameSettingsEditorState> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
let (metadata, document, input_bytes, controlled_keys) =
load_instance_document(instance_id, &state).await?;
let mut editor = build_editor_state(
Expand Down Expand Up @@ -335,7 +335,7 @@ pub async fn save_changes(
request: UpdateGameSettingsRequest,
) -> crate::Result<SaveGameSettingsResult> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
let (metadata, mut document, input_bytes, controlled_keys) =
load_instance_document(instance_id, &state).await?;
let current_editor = build_editor_state(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct Candidate {

pub(crate) fn queue_game_locale_index() {
if let Some(state) = State::get_if_initialized() {
state.game_locale_indexer.notify.notify_one();
state.synced_options.locales.notify.notify_one();
} else {
tracing::warn!(
"Game setting locales: cannot queue indexing before state initialization"
Expand All @@ -90,16 +90,17 @@ pub(crate) fn queue_game_locale_index() {

pub(crate) fn start_game_locale_indexer(state: Arc<State>) {
if state
.game_locale_indexer
.synced_options
.locales
.started
.swap(true, Ordering::AcqRel)
{
return;
}
state.game_locale_indexer.notify.notify_one();
state.synced_options.locales.notify.notify_one();
tokio::spawn(async move {
loop {
state.game_locale_indexer.notify.notified().await;
state.synced_options.locales.notify.notified().await;
tokio::time::sleep(std::time::Duration::from_millis(300)).await;
if let Err(error) = index_installed_sources(&state).await {
tracing::warn!(%error, "Game setting locales: indexing failed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ pub async fn capture_pack_base(
source: Option<GameOptionsPackSource>,
) -> crate::Result<()> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
let metadata = crate::state::get_instance(instance_id, &state.pool)
.await?
.ok_or(crate::ErrorKind::InputError("unknown instance".to_string()))?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ pub(super) async fn load_settings_editor(

pub async fn get_config() -> crate::Result<GameSettingsEditorState> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
load_settings_editor(&state).await
}

Expand All @@ -204,7 +204,7 @@ pub async fn preview_changes(
request: UpdateGameSettingsRequest,
) -> crate::Result<GameSettingsEditorState> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
if request.expected_catalog_revision != CATALOG_REVISION {
return load_settings_editor(&state).await;
}
Expand Down Expand Up @@ -277,7 +277,7 @@ pub async fn save_changes(
request: UpdateGameSettingsRequest,
) -> crate::Result<SaveGameSettingsResult> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
if !game_options_sync_is_enabled(&state.pool).await? {
bail!(ErrorKind::InputError(
"turn on game-settings sync before editing shared values"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ pub(in crate::api::instance) async fn initialize_from_source_instance(
pub async fn list_sync_sources()
-> crate::Result<Vec<GameOptionsSourceCandidate>> {
let state = State::get().await?;
let _guard = state.lock_synced_options().await;
let _guard = state.synced_options.lock().await;
let instances = crate::state::list_instances(&state.pool).await?;
let mut sources = Vec::with_capacity(instances.len());
for metadata in instances {
Expand Down
Loading
Loading