outl_exec/lib.rs
1//! # outl-exec
2//!
3//! Engine that runs the code inside a fenced markdown block (` ```lisp `,
4//! ` ```python `, ...) and writes the result back into the page as a
5//! sibling subblock — idempotent on re-run.
6//!
7//! The crate is intentionally tiny and modular:
8//!
9//! - [`runtime::Runtime`] — the only trait you implement to add a new
10//! language. Everything else (registry, orchestration, result block
11//! upkeep) treats runtimes as opaque.
12//! - [`registry::RuntimeRegistry`] — resolves a fence info-string
13//! (`"lisp"`, `"python"`, ...) to the concrete [`runtime::Runtime`].
14//! - [`sandbox`] — cross-platform timeout helper. Runtimes that need
15//! stronger isolation (memory, syscalls) layer it on top — the
16//! wasmtime-based runtimes coming in M2 will, the in-process ones
17//! today don't.
18//! - [`result_block`] — pure functions that find / create the result
19//! subblock under a code block. No I/O.
20//! - [`orchestrate::run_block_at_index`] — single entry point for every
21//! UI (TUI, future Tauri GUI, future mobile via uniffi). Takes a
22//! workspace + page path + block flat-index, runs, persists,
23//! reconciles.
24//!
25//! ## Adding a new language in 10 lines
26//!
27//! ```ignore
28//! struct RubyRuntime;
29//! impl outl_exec::Runtime for RubyRuntime {
30//! fn language(&self) -> &'static str { "ruby" }
31//! fn execute(&self, source: &str, ctx: &outl_exec::ExecContext)
32//! -> Result<outl_exec::ExecOutput, outl_exec::ExecError>
33//! {
34//! // run the source however you like (wasm, subprocess, ...);
35//! // populate stdout/stderr/duration/exit and return.
36//! todo!()
37//! }
38//! }
39//!
40//! let mut reg = outl_exec::RuntimeRegistry::default();
41//! reg.register(RubyRuntime);
42//! ```
43
44#![deny(unsafe_code)]
45#![warn(missing_docs)]
46
47pub mod language;
48pub mod orchestrate;
49pub mod registry;
50pub mod result_block;
51pub mod runtime;
52pub mod runtimes;
53pub mod sandbox;
54
55#[cfg(feature = "wasm")]
56pub mod wasm;
57
58pub use language::{extract_fence, FenceParts};
59pub use orchestrate::{
60 run_block_at_index, run_block_at_index_if_source_changed, RunError, RunReport,
61};
62pub use registry::RuntimeRegistry;
63pub use result_block::{
64 render_result_body, result_source_hash, source_hash, upsert_result_child,
65 upsert_result_child_with_hash, upsert_result_embeds, RESULT_MARKER, SOURCE_HASH_KEY,
66};
67pub use runtime::{ExecContext, ExecError, ExecOutput, ExitStatus, OutputFormat, Runtime};
68
69#[cfg(feature = "lang-query")]
70pub use runtimes::query::{run_query_dsl, run_query_structured, QueryHit, QueryParams};