first pass of merging in warp (doesn't build)

This commit is contained in:
Ryan Ward
2026-07-01 16:08:58 -05:00
parent 2f64909469
commit 4770ac06b5
3662 changed files with 414574 additions and 89772 deletions
+131 -9
View File
@@ -10,16 +10,17 @@ use std::path::Path;
use galaxy_core::HostId;
use galaxy_util::standardized_path::StandardizedPath;
use galaxyui::{AppContext, ModelContext, ModelHandle, SingletonEntity};
use galaxyui_core::{AppContext, ModelContext, ModelHandle, SingletonEntity};
use crate::file_tree_store::FileTreeState;
use crate::file_tree_update::RepoMetadataUpdate;
use crate::file_tree_update::{MetadataUpdateType, RepoMetadataUpdate};
use crate::local_model::{
GetContentsArgs, IndexedRepoState, LocalRepoMetadataModel, RepoContent, RepositoryMetadataEvent,
GetContentsArgs, IndexedRepoState, LocalRepoMetadataModel, RepoContents,
RepositoryMetadataEvent,
};
use crate::remote_model::{RemoteRepoMetadataModel, RemoteRepositoryMetadataEvent};
use crate::repository_identifier::{RemoteRepositoryIdentifier, RepositoryIdentifier};
use crate::RepoMetadataError;
use crate::{RepoMetadataError, StandingQueryResults, StandingQueryResultsDelta};
/// Unified events emitted by the [`RepoMetadataModel`] wrapper.
///
@@ -34,7 +35,17 @@ pub enum RepoMetadataEvent {
/// File trees for repositories were updated.
FileTreeUpdated { ids: Vec<RepositoryIdentifier> },
/// A file tree entry was updated.
FileTreeEntryUpdated { id: RepositoryIdentifier },
FileTreeEntryUpdated {
id: RepositoryIdentifier,
/// Specifies whether this event contains a precise delta or requires a conservative
/// refresh because the entry was replaced without one.
update_type: MetadataUpdateType,
},
/// Stored standing-query paths changed for a repository.
StandingQueryResultsUpdated {
id: RepositoryIdentifier,
delta: StandingQueryResultsDelta,
},
/// Updating a repository failed.
UpdatingRepositoryFailed { id: RepositoryIdentifier },
/// An incremental file tree update is ready to be sent to the remote
@@ -88,6 +99,7 @@ impl RepoMetadataModel {
fn forward_local_event(
&mut self,
_: ModelHandle<LocalRepoMetadataModel>,
event: &RepositoryMetadataEvent,
ctx: &mut ModelContext<Self>,
) {
@@ -110,9 +122,16 @@ impl RepoMetadataModel {
.collect(),
}
}
RepositoryMetadataEvent::FileTreeEntryUpdated { path } => {
RepositoryMetadataEvent::FileTreeEntryUpdated { path, update_type } => {
RepoMetadataEvent::FileTreeEntryUpdated {
id: RepositoryIdentifier::local(path.clone()),
update_type: update_type.clone(),
}
}
RepositoryMetadataEvent::StandingQueryResultsUpdated { path, delta } => {
RepoMetadataEvent::StandingQueryResultsUpdated {
id: RepositoryIdentifier::local(path.clone()),
delta: delta.clone(),
}
}
RepositoryMetadataEvent::UpdatingRepositoryFailed { path } => {
@@ -131,6 +150,7 @@ impl RepoMetadataModel {
fn forward_remote_event(
&mut self,
_: ModelHandle<RemoteRepoMetadataModel>,
event: &RemoteRepositoryMetadataEvent,
ctx: &mut ModelContext<Self>,
) {
@@ -154,9 +174,16 @@ impl RepoMetadataModel {
.collect(),
}
}
RemoteRepositoryMetadataEvent::FileTreeEntryUpdated { id } => {
RemoteRepositoryMetadataEvent::FileTreeEntryUpdated { id, update_type } => {
RepoMetadataEvent::FileTreeEntryUpdated {
id: RepositoryIdentifier::Remote(id.clone()),
update_type: update_type.clone(),
}
}
RemoteRepositoryMetadataEvent::StandingQueryResultsUpdated { id, delta } => {
RepoMetadataEvent::StandingQueryResultsUpdated {
id: RepositoryIdentifier::Remote(id.clone()),
delta: delta.clone(),
}
}
};
@@ -179,6 +206,21 @@ impl RepoMetadataModel {
}
}
pub fn standing_query_results<'a>(
&self,
id: &RepositoryIdentifier,
ctx: &'a AppContext,
) -> Option<&'a StandingQueryResults> {
match id {
RepositoryIdentifier::Local(path) => {
self.local.as_ref(ctx).standing_query_results(path)
}
RepositoryIdentifier::Remote(remote_id) => {
self.remote.as_ref(ctx).standing_query_results(remote_id)
}
}
}
/// Returns whether the given repository is indexed.
pub fn has_repository(&self, id: &RepositoryIdentifier, ctx: &AppContext) -> bool {
match id {
@@ -203,13 +245,42 @@ impl RepoMetadataModel {
}
}
/// Returns a future that resolves once repository indexing has completed at least once.
///
/// Callers should inspect [`Self::repository_state`] after awaiting this future to see whether
/// indexing succeeded or failed.
pub fn repository_indexed(
&self,
id: &RepositoryIdentifier,
ctx: &mut ModelContext<Self>,
) -> futures::future::BoxFuture<'static, ()> {
match id {
RepositoryIdentifier::Local(path) => {
let path = path.clone();
self.local
.update(ctx, |local, _| local.repository_indexed(&path))
}
RepositoryIdentifier::Remote(remote_id) => {
let remote_id = remote_id.clone();
self.remote
.update(ctx, |remote, _| remote.repository_indexed(&remote_id))
}
}
}
/// Returns repository contents for the specified repository.
///
/// The number of returned entries is capped; when the repository contains
/// more matching entries, the result is truncated and
/// [`RepoContents::truncated`] is set to `true`.
///
/// Returns an error if the repository is not indexed, indexing is pending, or indexing failed.
pub fn get_repo_contents<'a>(
&self,
id: &RepositoryIdentifier,
args: GetContentsArgs,
ctx: &'a AppContext,
) -> Option<Vec<RepoContent<'a>>> {
) -> Result<RepoContents<'a>, RepoMetadataError> {
match id {
RepositoryIdentifier::Local(path) => {
self.local.as_ref(ctx).get_repo_contents(path, args)
@@ -234,6 +305,18 @@ impl RepoMetadataModel {
// These delegate to the local sub-model. Remote equivalents will be
// added once the remote client ↔ server sync layer is in place.
/// Fully indexes a local directory identified by a standardized path.
#[cfg(feature = "local_fs")]
pub fn index_local_directory_path(
&self,
path: &StandardizedPath,
ctx: &mut ModelContext<Self>,
) -> Result<(), RepoMetadataError> {
let path = path.clone();
self.local
.update(ctx, |local, ctx| local.index_directory_path(&path, ctx))
}
/// Indexes a local repository from the given repository handle.
#[cfg(feature = "local_fs")]
pub fn index_directory(
@@ -272,6 +355,34 @@ impl RepoMetadataModel {
})
}
/// Registers paths that must be loaded even when gitignored or beyond the
/// tree's size limit.
///
/// This delegates to the local model because force-included path matching
/// happens while building local file trees. Remote repositories receive the
/// resulting file-tree metadata over the existing remote sync protocol.
pub fn register_force_included_paths(
&self,
paths: impl IntoIterator<Item = std::path::PathBuf>,
ctx: &mut ModelContext<Self>,
) {
let paths: Vec<_> = paths.into_iter().collect();
self.local.update(ctx, |local, _| {
local.register_force_included_paths(paths);
});
}
pub fn set_project_skill_provider_paths(
&self,
paths: impl IntoIterator<Item = std::path::PathBuf>,
ctx: &mut ModelContext<Self>,
) {
let paths: Vec<_> = paths.into_iter().collect();
self.local.update(ctx, |local, _| {
local.set_project_skill_provider_paths(paths);
});
}
/// Removes a lazily-loaded local standalone path from tracking.
#[cfg(feature = "local_fs")]
pub fn remove_lazy_loaded_path(&self, path: &StandardizedPath, ctx: &mut ModelContext<Self>) {
@@ -356,7 +467,7 @@ impl RepoMetadataModel {
}
}
impl galaxyui::Entity for RepoMetadataModel {
impl galaxyui_core::Entity for RepoMetadataModel {
type Event = RepoMetadataEvent;
}
@@ -375,4 +486,15 @@ impl RepoMetadataModel {
local.insert_test_state(repo_path, state);
});
}
pub fn insert_test_standing_results(
&self,
repo_path: StandardizedPath,
standing_results: StandingQueryResults,
ctx: &mut ModelContext<Self>,
) {
self.local.update(ctx, |local, _ctx| {
local.insert_test_standing_results(repo_path, standing_results);
});
}
}