use std::sync::Arc;
use crate::Result;
use crate::core::config::{ExtractInput, ExtractionConfig, ExtractionResult};
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
mod crawl_handle;
mod extract_impl;
pub mod seams;
#[cfg(feature = "heuristics")]
pub mod structured;
#[cfg(all(feature = "heuristics", feature = "pdf"))]
pub mod parsed;
use seams::{CacheBackend, NoopCache, NoopProgressSink, ProgressSink};
#[cfg(feature = "presets")]
use seams::{CorePresetResolver, PresetResolver};
#[cfg(feature = "layout-detection")]
use seams::{DefaultModelProvider, ModelProvider};
#[cfg(feature = "heuristics")]
use seams::{DefaultStructuredPolicy, StructuredPolicy};
#[cfg(feature = "liter-llm")]
use seams::{LiterLlmClient, LlmClient};
struct EngineInner {
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
crawl: parking_lot::Mutex<Option<crawl_handle::CrawlHandleMemo>>,
cache: Arc<dyn CacheBackend>,
progress: Arc<dyn ProgressSink>,
#[cfg(feature = "heuristics")]
structured_policy: Arc<dyn StructuredPolicy>,
#[cfg(feature = "presets")]
preset_resolver: Arc<dyn PresetResolver>,
#[cfg(feature = "liter-llm")]
llm_client: Arc<dyn LlmClient>,
#[cfg(feature = "layout-detection")]
model_provider: Arc<dyn ModelProvider>,
}
#[derive(Clone)]
pub struct Engine {
inner: Arc<EngineInner>,
}
impl Engine {
pub fn builder() -> EngineBuilder {
EngineBuilder::default()
}
pub fn new_default() -> Self {
EngineBuilder::default().build()
}
pub async fn extract(&self, input: ExtractInput, config: &ExtractionConfig) -> Result<ExtractionResult> {
extract_impl::extract(input, config).await
}
pub async fn extract_batch(
&self,
inputs: Vec<ExtractInput>,
config: &ExtractionConfig,
) -> Result<ExtractionResult> {
extract_impl::extract_batch(&self.inner, inputs, config).await
}
pub fn cache_backend(&self) -> &Arc<dyn CacheBackend> {
&self.inner.cache
}
pub fn progress_sink(&self) -> &Arc<dyn ProgressSink> {
&self.inner.progress
}
#[cfg(feature = "heuristics")]
pub fn structured_policy(&self) -> &Arc<dyn StructuredPolicy> {
&self.inner.structured_policy
}
#[cfg(feature = "presets")]
pub fn preset_resolver(&self) -> &Arc<dyn PresetResolver> {
&self.inner.preset_resolver
}
#[cfg(feature = "liter-llm")]
pub fn llm_client(&self) -> &Arc<dyn LlmClient> {
&self.inner.llm_client
}
#[cfg(feature = "layout-detection")]
pub fn model_provider(&self) -> &Arc<dyn ModelProvider> {
&self.inner.model_provider
}
}
#[derive(Default)]
pub struct EngineBuilder {
cache: Option<Arc<dyn CacheBackend>>,
progress: Option<Arc<dyn ProgressSink>>,
#[cfg(feature = "heuristics")]
structured_policy: Option<Arc<dyn StructuredPolicy>>,
#[cfg(feature = "presets")]
preset_resolver: Option<Arc<dyn PresetResolver>>,
#[cfg(feature = "liter-llm")]
llm_client: Option<Arc<dyn LlmClient>>,
#[cfg(feature = "layout-detection")]
model_provider: Option<Arc<dyn ModelProvider>>,
}
impl EngineBuilder {
pub fn with_cache_backend(mut self, cache: Arc<dyn CacheBackend>) -> Self {
self.cache = Some(cache);
self
}
pub fn with_progress_sink(mut self, progress: Arc<dyn ProgressSink>) -> Self {
self.progress = Some(progress);
self
}
#[cfg(feature = "heuristics")]
pub fn with_structured_policy(mut self, policy: Arc<dyn StructuredPolicy>) -> Self {
self.structured_policy = Some(policy);
self
}
#[cfg(feature = "presets")]
pub fn with_preset_resolver(mut self, resolver: Arc<dyn PresetResolver>) -> Self {
self.preset_resolver = Some(resolver);
self
}
#[cfg(feature = "liter-llm")]
pub fn with_llm_client(mut self, client: Arc<dyn LlmClient>) -> Self {
self.llm_client = Some(client);
self
}
#[cfg(feature = "layout-detection")]
pub fn with_model_provider(mut self, provider: Arc<dyn ModelProvider>) -> Self {
self.model_provider = Some(provider);
self
}
pub fn build(self) -> Engine {
let inner = EngineInner {
#[cfg(all(feature = "url-ingestion", feature = "tokio-runtime", not(target_arch = "wasm32")))]
crawl: parking_lot::Mutex::new(None),
cache: self.cache.unwrap_or_else(|| Arc::new(NoopCache)),
progress: self.progress.unwrap_or_else(|| Arc::new(NoopProgressSink)),
#[cfg(feature = "heuristics")]
structured_policy: self
.structured_policy
.unwrap_or_else(|| Arc::new(DefaultStructuredPolicy::default())),
#[cfg(feature = "presets")]
preset_resolver: self.preset_resolver.unwrap_or_else(|| Arc::new(CorePresetResolver)),
#[cfg(feature = "liter-llm")]
llm_client: self.llm_client.unwrap_or_else(|| Arc::new(LiterLlmClient)),
#[cfg(feature = "layout-detection")]
model_provider: self
.model_provider
.unwrap_or_else(|| Arc::new(DefaultModelProvider::default())),
};
Engine { inner: Arc::new(inner) }
}
}