Skip to content

Commit

Permalink
dev(compiler): add actor for watch compiler (#371)
Browse files Browse the repository at this point in the history
* dev(compiler): init notify access model

* dev(compiler): generalize {with,set}_exporter

* dev(compiler): notify stage1

* dev(compiler): remove high-level workaround

* dev(compiler): prefer `Arc<Document>`

* dev(compiler): refactor a bit

* dev(compiler): detect undetermined notify
+ at low-level
+ state-based detection

* dev(compiler): add more comments

* dev: compress event triggering compilation

* dev: synchronize memory change with NotifyActor

* dev: optimize hot path to memory editting

* docs: add more comments

* dev: clean logging

* docs: add more comments

* fix: warning

* fix: doc example

* dev(compiler): cheaper path clone

* fix: doc example again
  • Loading branch information
Myriad-Dreamin authored Sep 27, 2023
1 parent ccee54f commit a30cad9
Show file tree
Hide file tree
Showing 29 changed files with 1,850 additions and 370 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions cli/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::path::Path;

use typst::doc::Document;
use typst_ts_compiler::{
service::{CompileDriver, CompileExporter, Compiler, DynamicLayoutCompiler, WatchDriver},
service::{CompileActor, CompileDriver, CompileExporter, Compiler, DynamicLayoutCompiler},
TypstSystemWorld,
};
use typst_ts_core::{config::CompileOpts, exporter_builtins::GroupExporter, path::PathClean};
Expand Down Expand Up @@ -104,9 +104,9 @@ pub fn compile_export(args: CompileArgs, exporter: GroupExporter<Document>) -> !
// CompileExporter + DynamicLayoutCompiler + WatchDriver
let driver = CompileExporter::new(driver).with_exporter(exporter);
let driver = DynamicLayoutCompiler::new(driver, output_dir).with_enable(args.dynamic_layout);
let mut driver = WatchDriver::new(driver, watch_root).with_enable(args.watch);
let actor = CompileActor::new(driver, watch_root).with_watch(args.watch);

utils::async_continue(async move {
utils::logical_exit(driver.compile().await);
utils::logical_exit(actor.run());
})
}
17 changes: 9 additions & 8 deletions cli/src/query_repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustyline::hint::{Hinter, HistoryHinter};
use rustyline::validate::MatchingBracketValidator;
use rustyline::{Cmd, CompletionType, Config, EditMode, Editor, KeyEvent};
use rustyline::{Helper, Validator};
use typst_ts_core::TakeAs;

use crate::query::serialize;
use crate::CompileOnceArgs;
Expand Down Expand Up @@ -123,7 +124,7 @@ impl Completer for ReplContext {
driver.world.reset();
let typst_completions = driver
.with_shadow_file_by_id(main_id, dyn_content.as_bytes().into(), |driver| {
let frames = driver.compile().map(|d| d.pages);
let frames = driver.compile().map(|d| d.take().pages);
let frames = frames.as_ref().map(|v| v.as_slice()).unwrap_or_default();
let source = driver.world.main();
Ok(autocomplete(&driver.world, frames, &source, cursor, true))
Expand Down Expand Up @@ -226,13 +227,13 @@ pub fn start_repl_test(args: CompileOnceArgs) -> rustyline::Result<()> {

impl ReplContext {
fn repl_process_line(&mut self, line: String) {
let compiled =
self.driver
.borrow_mut()
.with_compile_diag::<false, _>(|driver: &mut CompileDriver| {
let doc = driver.compile()?;
driver.query(line, &doc)
});
let compiled = self.driver.borrow_mut().with_stage_diag::<false, _>(
"compiling",
|driver: &mut CompileDriver| {
let doc = driver.compile()?;
driver.query(line, &doc)
},
);

if let Some(compiled) = compiled {
let serialized = serialize(&compiled, "json").unwrap();
Expand Down
5 changes: 3 additions & 2 deletions compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ serde.workspace = true
serde_json.workspace = true
serde-wasm-bindgen = { workspace = true, optional = true }

same-file = { version = "1", optional = true }

memmap2 = { workspace = true, optional = true }
dirs = { workspace = true, optional = true }
walkdir = { workspace = true, optional = true }
Expand All @@ -43,7 +45,6 @@ nohash-hasher.workspace = true
pathdiff.workspace = true
dissimilar.workspace = true
tar.workspace = true

wasm-bindgen = { workspace = true, optional = true }
wasm-bindgen-futures = { workspace = true, optional = true }
js-sys = { workspace = true, optional = true }
Expand Down Expand Up @@ -88,7 +89,7 @@ system-compile = [
"dep:notify",
"dep:log",
]
system-watch = ["dep:notify", "dep:tokio"]
system-watch = ["dep:notify", "dep:tokio", "dep:same-file"]
system = ["system-compile", "system-watch"]
dynamic-layout = ["dep:typst-ts-svg-exporter"]
__web = [
Expand Down
24 changes: 21 additions & 3 deletions compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ pub mod service;
/// Run the compiler in the system environment.
#[cfg(feature = "system-compile")]
pub(crate) mod system;
use std::path::{Path, PathBuf};
use std::{
path::{Path, PathBuf},
sync::Arc,
};

#[cfg(feature = "system-compile")]
pub use system::TypstSystemWorld;
Expand All @@ -63,16 +66,24 @@ use typst::{
diag::{At, FileResult, SourceResult},
syntax::Span,
};
use typst_ts_core::{Bytes, TypstFileId};
use typst_ts_core::{Bytes, ImmutPath, TypstFileId};
use vfs::notify::FilesystemEvent;

/// Latest version of the shadow api, which is in beta.
pub trait ShadowApi {
fn _shadow_map_id(&self, _file_id: TypstFileId) -> FileResult<PathBuf> {
unimplemented!()
}

/// Get the shadow files.
fn shadow_paths(&self) -> Vec<Arc<Path>>;

/// Reset the shadow files.
fn reset_shadow(&mut self);
fn reset_shadow(&mut self) {
for path in self.shadow_paths() {
self.unmap_shadow(&path).unwrap();
}
}

/// Add a shadow file to the driver.
fn map_shadow(&self, path: &Path, content: Bytes) -> FileResult<()>;
Expand Down Expand Up @@ -123,3 +134,10 @@ pub trait ShadowApi {
self.with_shadow_file(&file_path, content, f)
}
}

/// Latest version of the notify api, which is in beta.
pub trait NotifyApi {
fn iter_dependencies<'a>(&'a self, f: &mut dyn FnMut(&'a ImmutPath, instant::SystemTime));

fn notify_fs_event(&mut self, event: FilesystemEvent);
}
Loading

0 comments on commit a30cad9

Please sign in to comment.