use std::sync::Arc;
use reflexo::error::prelude::*;
use typst::model::Document;
use super::ir::{
FlatModule, IncrFontPack, IncrGlyphPack, ItemPack, LayoutRegion, LayoutRegionNode,
ModuleMetadata, VecDocument,
};
use super::pass::IncrTypst2VecPass;
use crate::debug_loc::{ElementPoint, SourceSpanOffset};
pub use reflexo::vector::incr::{IncrDocClient, IncrDocClientKern};
#[derive(Default)]
pub struct IncrDocServer {
doc_view: Option<VecDocument>,
typst2vec: IncrTypst2VecPass,
}
impl IncrDocServer {
pub fn set_should_attach_debug_info(&mut self, should_attach_debug_info: bool) {
self.typst2vec
.spans
.set_should_attach_debug_info(should_attach_debug_info);
}
pub fn pack_delta(&mut self, output: Arc<Document>) -> Vec<u8> {
self.typst2vec.spans.reset();
self.typst2vec.increment_lifetime();
let gc_items = self.typst2vec.gc(5 * 2);
let pages = self.typst2vec.doc(&output.introspector, &output);
let delta = self.typst2vec.finalize_delta();
#[cfg(feature = "debug-gc")]
{
let mi = self
.typst2vec
.items
.clone()
.into_iter()
.map(|i| i.1 .0)
.min()
.unwrap_or(0);
println!(
"gc[{}]: max: {}, min: {}, remove: {}",
self.typst2vec.lifetime,
self.typst2vec
.items
.clone()
.into_iter()
.map(|i| i.1 .0)
.max()
.unwrap_or(0xffffffff),
mi,
gc_items.len()
);
}
let fonts = IncrFontPack {
items: delta.fonts,
incremental_base: 0, };
let glyphs = IncrGlyphPack {
items: delta.glyphs,
incremental_base: 0, };
let pages = LayoutRegionNode::new_pages(pages.clone());
let pages = Arc::new(vec![LayoutRegion::new_single(pages)]);
let delta = FlatModule::new(vec![
ModuleMetadata::GarbageCollection(gc_items),
ModuleMetadata::Font(Arc::new(fonts)),
ModuleMetadata::Glyph(Arc::new(glyphs)),
ModuleMetadata::Item(ItemPack(delta.items.clone().into_iter().collect())),
ModuleMetadata::Layout(pages),
])
.to_bytes();
[b"diff-v1,", delta.as_slice()].concat()
}
pub fn pack_current(&mut self) -> Option<Vec<u8>> {
let doc = self.doc_view.as_ref()?;
let (fonts, glyphs) = self.typst2vec.glyphs.finalize();
let pages = LayoutRegionNode::new_pages(doc.pages.clone());
let pages = Arc::new(vec![LayoutRegion::new_single(pages)]);
let delta = FlatModule::new(vec![
ModuleMetadata::Font(Arc::new(fonts.into())),
ModuleMetadata::Glyph(Arc::new(glyphs.into())),
ModuleMetadata::Item(ItemPack(doc.module.items.clone().into_iter().collect())),
ModuleMetadata::Layout(pages),
])
.to_bytes();
Some([b"new,", delta.as_slice()].concat())
}
pub fn resolve_element_paths_by_span(
&mut self,
span_offset: SourceSpanOffset,
) -> ZResult<Vec<Vec<ElementPoint>>> {
self.typst2vec.spans.query_element_paths(span_offset)
}
pub fn resolve_span_by_element_path(
&mut self,
path: &[ElementPoint],
) -> ZResult<Option<(SourceSpanOffset, SourceSpanOffset)>> {
self.typst2vec.spans.query(path)
}
}