chore: Move component_preview into zed (#30480)

This improves our build times by ~0.2s

Closes #ISSUE

Release Notes:

- N/A
This commit is contained in:
Piotr Osiewicz 2025-05-11 00:25:35 +02:00 committed by GitHub
parent e4525b80f8
commit 5ba1d3edec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 10 additions and 71 deletions

View file

@ -658,7 +658,7 @@ fn main() {
let app_state = app_state.clone();
component_preview::init(app_state.clone(), cx);
crate::zed::component_preview::init(app_state.clone(), cx);
cx.spawn(async move |cx| {
while let Some(urls) = open_rx.next().await {

View file

@ -1,4 +1,5 @@
mod app_menus;
pub mod component_preview;
pub mod inline_completion_registry;
#[cfg(target_os = "macos")]
pub(crate) mod mac_only_instance;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
use anyhow::Result;
use db::{define_connection, query, sqlez::statement::Statement, sqlez_macros::sql};
use workspace::{ItemId, WorkspaceDb, WorkspaceId};
define_connection! {
pub static ref COMPONENT_PREVIEW_DB: ComponentPreviewDb<WorkspaceDb> =
&[sql!(
CREATE TABLE component_previews (
workspace_id INTEGER,
item_id INTEGER UNIQUE,
active_page_id TEXT,
PRIMARY KEY(workspace_id, item_id),
FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id)
ON DELETE CASCADE
) STRICT;
)];
}
impl ComponentPreviewDb {
pub async fn save_active_page(
&self,
item_id: ItemId,
workspace_id: WorkspaceId,
active_page_id: String,
) -> Result<()> {
log::debug!(
"Saving active page: item_id={item_id:?}, workspace_id={workspace_id:?}, active_page_id={active_page_id}"
);
let query = "INSERT INTO component_previews(item_id, workspace_id, active_page_id)
VALUES (?1, ?2, ?3)
ON CONFLICT DO UPDATE SET
active_page_id = ?3";
self.write(move |conn| {
let mut statement = Statement::prepare(conn, query)?;
let mut next_index = statement.bind(&item_id, 1)?;
next_index = statement.bind(&workspace_id, next_index)?;
statement.bind(&active_page_id, next_index)?;
statement.exec()
})
.await
}
query! {
pub fn get_active_page(item_id: ItemId, workspace_id: WorkspaceId) -> Result<Option<String>> {
SELECT active_page_id
FROM component_previews
WHERE item_id = ? AND workspace_id = ?
}
}
}

View file

@ -0,0 +1 @@
pub mod active_thread;

View file

@ -0,0 +1,101 @@
use agent::{ActiveThread, ContextStore, MessageSegment, TextThreadStore, ThreadStore};
use anyhow::{Result, anyhow};
use assistant_tool::ToolWorkingSet;
use gpui::{AppContext, AsyncApp, Entity, Task, WeakEntity};
use indoc::indoc;
use languages::LanguageRegistry;
use project::Project;
use prompt_store::PromptBuilder;
use std::sync::Arc;
use ui::{App, Window};
use workspace::Workspace;
pub fn load_preview_thread_store(
workspace: WeakEntity<Workspace>,
project: Entity<Project>,
cx: &mut AsyncApp,
) -> Task<Result<Entity<ThreadStore>>> {
workspace
.update(cx, |_, cx| {
ThreadStore::load(
project.clone(),
cx.new(|_| ToolWorkingSet::default()),
None,
Arc::new(PromptBuilder::new(None).unwrap()),
cx,
)
})
.unwrap_or(Task::ready(Err(anyhow!("workspace dropped"))))
}
pub fn load_preview_text_thread_store(
workspace: WeakEntity<Workspace>,
project: Entity<Project>,
cx: &mut AsyncApp,
) -> Task<Result<Entity<TextThreadStore>>> {
workspace
.update(cx, |_, cx| {
TextThreadStore::new(
project.clone(),
Arc::new(PromptBuilder::new(None).unwrap()),
Default::default(),
cx,
)
})
.unwrap_or(Task::ready(Err(anyhow!("workspace dropped"))))
}
pub fn static_active_thread(
workspace: WeakEntity<Workspace>,
project: Entity<Project>,
language_registry: Arc<LanguageRegistry>,
thread_store: Entity<ThreadStore>,
text_thread_store: Entity<TextThreadStore>,
window: &mut Window,
cx: &mut App,
) -> Entity<ActiveThread> {
let context_store =
cx.new(|_| ContextStore::new(project.downgrade(), Some(thread_store.downgrade())));
let thread = thread_store.update(cx, |thread_store, cx| thread_store.create_thread(cx));
thread.update(cx, |thread, cx| {
thread.insert_assistant_message(vec![
MessageSegment::Text(indoc! {"
I'll help you fix the lifetime error in your `cx.spawn` call. When working with async operations in GPUI, there are specific patterns to follow for proper lifetime management.
Let's look at what's happening in your code:
---
Let's check the current state of the active_thread.rs file to understand what might have changed:
---
Looking at the implementation of `load_preview_thread_store` and understanding GPUI's async patterns, here's the issue:
1. `load_preview_thread_store` returns a `Task<anyhow::Result<Entity<ThreadStore>>>`, which means it's already a task.
2. When you call this function inside another `spawn` call, you're nesting tasks incorrectly.
Here's the correct way to implement this:
---
The problem is in how you're setting up the async closure and trying to reference variables like `window` and `language_registry` that aren't accessible in that scope.
Here's how to fix it:
"}.to_string()),
], cx);
});
cx.new(|cx| {
ActiveThread::new(
thread,
thread_store,
text_thread_store,
context_store,
language_registry,
workspace.clone(),
window,
cx,
)
})
}