Skip to content

Commit

Permalink
feat: remove typ_client
Browse files Browse the repository at this point in the history
  • Loading branch information
Myriad-Dreamin committed Jan 17, 2025
1 parent 760ba94 commit cda7a4f
Show file tree
Hide file tree
Showing 11 changed files with 426 additions and 495 deletions.
193 changes: 0 additions & 193 deletions crates/tinymist/src/actor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,196 +3,3 @@
pub mod editor;
#[cfg(feature = "preview")]
pub mod preview;
pub mod typ_client;

use std::sync::Arc;

use reflexo::ImmutPath;
use reflexo_typst::watch_deps;
use reflexo_typst::world::EntryState;
use tinymist_query::analysis::{Analysis, PeriscopeProvider};
use tinymist_query::{ExportKind, LocalContext, VersionedDocument};
use tinymist_render::PeriscopeRenderer;
use tinymist_world::LspInterrupt;
use typst::layout::Position;

use crate::stats::CompilerQueryStats;
use crate::{
task::{ExportConfig, ExportTask, ExportUserConfig},
world::{ImmutDict, LspUniverseBuilder},
LanguageState,
};
use tinymist_world::project::{CompileServerOpts, ProjectCompiler};
use typ_client::{CompileClientActor, LocalCompileHandler, LspProjectHandler};

impl LanguageState {
/// Restart the primary server.
pub fn restart_primary(&mut self) {
let entry = self.entry_resolver().resolve_default();
self.restart_server("primary", entry);
}

/// Restart the server with the given group.
pub fn restart_dedicate(&mut self, dedicate: &str, entry: Option<ImmutPath>) {
self.restart_server(dedicate, entry);
}

/// Restart the server with the given group.
fn restart_server(&mut self, group: &str, entry: Option<ImmutPath>) {
let server = self.server(
group.to_owned(),
self.entry_resolver().resolve(entry),
self.compile_config().determine_inputs(),
);

let prev = if group == "primary" {
self.primary.replace(server)
} else {
let cell = self
.dedicates
.iter_mut()
.find(|dedicate| dedicate.handle.diag_group == group);
if let Some(dedicate) = cell {
Some(std::mem::replace(dedicate, server))
} else {
self.dedicates.push(server);
None
}
};

if let Some(mut prev) = prev {
self.client.handle.spawn(async move { prev.settle().await });
}
}

/// Create a new server for the given group.
pub fn server(
&self,
diag_group: String,
entry: EntryState,
inputs: ImmutDict,
) -> CompileClientActor {
// Run Export actors before preparing cluster to avoid loss of events
let config = ExportConfig {
group: diag_group.clone(),
editor_tx: Some(self.editor_tx.clone()),
config: ExportUserConfig {
output: self.compile_config().output_path.clone(),
mode: self.compile_config().export_pdf,
},
kind: ExportKind::Pdf {
creation_timestamp: self.config.compile.determine_creation_timestamp(),
},
count_words: self.config.compile.notify_status,
};
let export = ExportTask::new(self.client.handle.clone(), config);

log::info!(
"TypstActor: creating server for {diag_group}, entry: {entry:?}, inputs: {inputs:?}"
);

// Create the compile handler for client consuming results.
let const_config = self.const_config();
let periscope_args = self.compile_config().periscope_args.clone();
let handle = Arc::new(LspProjectHandler {
#[cfg(feature = "preview")]
inner: std::sync::Arc::new(parking_lot::RwLock::new(None)),
diag_group: diag_group.clone(),
export: export.clone(),
editor_tx: self.editor_tx.clone(),
client: Box::new(self.client.clone().to_untyped()),
analysis: Arc::new(Analysis {
position_encoding: const_config.position_encoding,
allow_overlapping_token: const_config.tokens_overlapping_token_support,
allow_multiline_token: const_config.tokens_multiline_token_support,
remove_html: !self.config.support_html_in_markdown,
completion_feat: self.config.completion.clone(),
color_theme: match self.compile_config().color_theme.as_deref() {
Some("dark") => tinymist_query::ColorTheme::Dark,
_ => tinymist_query::ColorTheme::Light,
},
periscope: periscope_args.map(|args| {
let r = TypstPeriscopeProvider(PeriscopeRenderer::new(args));
Arc::new(r) as Arc<dyn PeriscopeProvider + Send + Sync>
}),
tokens_caches: Arc::default(),
workers: Default::default(),
caches: Default::default(),
analysis_rev_cache: Arc::default(),
stats: Arc::default(),
}),

notified_revision: parking_lot::Mutex::new(0),
});

let font_resolver = self.compile_config().determine_fonts();
let entry_ = entry.clone();
let compile_handle = handle.clone();
let cert_path = self.compile_config().determine_certification_path();
let package = self.compile_config().determine_package_opts();

// todo: never fail?
let default_fonts = Arc::new(LspUniverseBuilder::only_embedded_fonts().unwrap());
let package_registry =
LspUniverseBuilder::resolve_package(cert_path.clone(), Some(&package));
let verse =
LspUniverseBuilder::build(entry_.clone(), inputs, default_fonts, package_registry)
.expect("incorrect options");

// todo: unify filesystem watcher
let (dep_tx, dep_rx) = tokio::sync::mpsc::unbounded_channel();
let client = self.client.clone().to_untyped();
let async_handle = client.handle.clone();
async_handle.spawn(watch_deps(dep_rx, move |event| {
client.send_event(LspInterrupt::Fs(event));
}));

// Create the actor
let server = ProjectCompiler::new_with(
verse,
dep_tx,
CompileServerOpts {
compile_handle,
..Default::default()
},
);
let client = self.client.clone();
self.client.handle.spawn_blocking(move || {
// Create the world
let font_resolver = font_resolver.wait().clone();
client.send_event(LspInterrupt::Font(font_resolver));
});

let handle = LocalCompileHandler {
diag_group,
wrapper: server,
analysis: handle.analysis.clone(),
stats: CompilerQueryStats::default(),
export: handle.export.clone(),
};

// Create the client
let config = self.compile_config().clone();

// todo: restart loses the memory changes
// We do send memory changes instead of initializing compiler with them.
// This is because there are state recorded inside of the compiler actor, and we
// must update them.
// client.add_memory_changes(MemoryEvent::Update(snapshot));
CompileClientActor::new(handle, config, entry)
}
}

struct TypstPeriscopeProvider(PeriscopeRenderer);

impl PeriscopeProvider for TypstPeriscopeProvider {
/// Resolve periscope image at the given position.
fn periscope_at(
&self,
ctx: &mut LocalContext,
doc: VersionedDocument,
pos: Position,
) -> Option<String> {
self.0.render_marked(ctx, doc, pos)
}
}
26 changes: 13 additions & 13 deletions crates/tinymist/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ impl LanguageState {
/// Clear all cached resources.
pub fn clear_cache(&mut self, _arguments: Vec<JsonValue>) -> AnySchedulableResponse {
comemo::evict(0);
self.primary().clear_cache();
self.handle.analysis.clear_cache();
just_ok(JsonValue::Null)
}

Expand Down Expand Up @@ -252,8 +252,8 @@ impl LanguageState {
) -> SchedulableResponse<crate::tool::preview::StartPreviewResponse> {
use std::path::Path;

use crate::project::ProjectExt;
use crate::tool::preview::PreviewCliArgs;
use actor::typ_client::ProjectExt;
use clap::Parser;

let cli_args = get_arg_or_default!(args[0] as Vec<String>);
Expand Down Expand Up @@ -285,7 +285,7 @@ impl LanguageState {

let previewer = typst_preview::PreviewBuilder::new(cli_args.preview.clone());

let handle = &mut self.primary().handle;
let handle = &mut self.handle;
let primary = &mut handle.wrapper.primary;
let _ = ProjectExt::unregister_preview;
if !cli_args.not_as_primary && primary.ext.register_preview(previewer.compile_watcher()) {
Expand Down Expand Up @@ -358,7 +358,7 @@ impl LanguageState {
let from_source = get_arg!(args[0] as String);
let to_path = get_arg!(args[1] as Option<PathBuf>).map(From::from);

let snap = self.primary().snapshot().map_err(z_internal_error)?;
let snap = self.snapshot().map_err(z_internal_error)?;

just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
Expand Down Expand Up @@ -403,7 +403,7 @@ impl LanguageState {

let from_source = get_arg!(args[0] as String);

let snap = self.primary().snapshot().map_err(z_internal_error)?;
let snap = self.snapshot().map_err(z_internal_error)?;

just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
Expand Down Expand Up @@ -471,7 +471,7 @@ impl LanguageState {

let entry = self.entry_resolver().resolve(Some(path));

let snap = self.primary().snapshot().map_err(z_internal_error)?;
let snap = self.snapshot().map_err(z_internal_error)?;
let user_action = self.user_action;

just_future(async move {
Expand Down Expand Up @@ -539,13 +539,13 @@ impl LanguageState {
impl LanguageState {
/// Get the all valid fonts
pub fn resource_fonts(&mut self, _arguments: Vec<JsonValue>) -> AnySchedulableResponse {
let snapshot = self.primary().snapshot().map_err(z_internal_error)?;
let snapshot = self.snapshot().map_err(z_internal_error)?;
just_future(Self::get_font_resources(snapshot))
}

/// Get the all valid symbols
pub fn resource_symbols(&mut self, _arguments: Vec<JsonValue>) -> AnySchedulableResponse {
let snapshot = self.primary().snapshot().map_err(z_internal_error)?;
let snapshot = self.snapshot().map_err(z_internal_error)?;
just_future(Self::get_symbol_resources(snapshot))
}

Expand All @@ -562,7 +562,7 @@ impl LanguageState {

/// Get directory of packages
pub fn resource_package_dirs(&mut self, _arguments: Vec<JsonValue>) -> AnySchedulableResponse {
let snap = self.primary().snapshot().map_err(z_internal_error)?;
let snap = self.snapshot().map_err(z_internal_error)?;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
let paths = snap.world.registry.paths();
Expand All @@ -576,7 +576,7 @@ impl LanguageState {
&mut self,
_arguments: Vec<JsonValue>,
) -> AnySchedulableResponse {
let snap = self.primary().snapshot().map_err(z_internal_error)?;
let snap = self.snapshot().map_err(z_internal_error)?;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
let paths = snap.world.registry.local_path();
Expand All @@ -592,7 +592,7 @@ impl LanguageState {
) -> AnySchedulableResponse {
let ns = get_arg!(arguments[1] as EcoString);

let snap = self.primary().snapshot().map_err(z_internal_error)?;
let snap = self.snapshot().map_err(z_internal_error)?;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
let packages =
Expand All @@ -610,7 +610,7 @@ impl LanguageState {
&mut self,
mut arguments: Vec<JsonValue>,
) -> AnySchedulableResponse {
let fut = self.primary().query_snapshot().map_err(internal_error)?;
let fut = self.query_snapshot().map_err(internal_error)?;
let info = get_arg!(arguments[1] as PackageInfo);

just_future(async move {
Expand Down Expand Up @@ -670,7 +670,7 @@ impl LanguageState {
info: PackageInfo,
f: impl FnOnce(&mut LocalContextGuard) -> LspResult<T> + Send + Sync,
) -> LspResult<impl Future<Output = LspResult<T>>> {
let fut = self.primary().query_snapshot().map_err(internal_error)?;
let fut = self.query_snapshot().map_err(internal_error)?;

Ok(async move {
let snap = fut.receive().await.map_err(z_internal_error)?;
Expand Down
4 changes: 3 additions & 1 deletion crates/tinymist/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
mod actor;
mod cmd;
mod init;
mod project;
mod resource;
mod server;
mod stats;
Expand All @@ -35,12 +36,13 @@ pub use server::*;
pub use sync_lsp::LspClient;
pub use tinymist_query as query;
pub use tinymist_world as world;
pub use world::*;
pub use world::{CompileFontArgs, CompileOnceArgs, CompilePackageArgs};

use lsp_server::{RequestId, ResponseError};
use serde_json::from_value;
use sync_lsp::*;
use utils::*;
use world::*;

use tinymist_query::CompilerQueryResponse;

Expand Down
4 changes: 2 additions & 2 deletions crates/tinymist/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub fn trace_lsp_main(args: TraceLspArgs) -> anyhow::Result<()> {

let entry = state.entry_resolver().resolve(Some(input.as_path().into()));

let snap = state.primary().snapshot().unwrap();
let snap = state.snapshot().unwrap();

RUNTIMES.tokio_runtime.block_on(async {
let snap = snap.receive().await.unwrap();
Expand Down Expand Up @@ -266,7 +266,7 @@ pub fn query_main(cmds: QueryCommands) -> anyhow::Result<()> {

let state = service.state_mut().unwrap();

let snap = state.primary().snapshot().unwrap();
let snap = state.snapshot().unwrap();
let res = RUNTIMES.tokio_runtime.block_on(async move {
let w = snap.receive().await.map_err(internal_error)?;
match cmds {
Expand Down
Loading

0 comments on commit cda7a4f

Please sign in to comment.