korvin-core 0.2.1

The core for korvin frontend framework
Documentation
use data::ElementId;
use dom_executor::DomExecutor;
pub use js_sys;
use mutation::error::MutationError;
use raw_operations::error::{DebugOf, RawOperationError};
use thiserror::Error;
pub use web_sys;
use web_sys::{Document, Element};
pub mod flavors;

thread_local! {
    pub static DOCUMENT: web_sys::Document = crate::get_document().expect("document not present");
}

pub mod data;
pub mod document_model;
pub mod dom_executor;
pub mod element_builder;
pub mod mutation;
pub mod raw_operations;
pub mod utils;

#[derive(Error, Debug)]
pub enum RuntimeError {
    #[error("No window")]
    NoWindow,
    #[error("No document")]
    NoDocument,
    #[error("No root element (body)")]
    NoRootElement,
    #[error("Executing a mutation: {0}")]
    Mutation(#[source] mutation::error::MutationError),
    #[error("Nothing to revert, revert stack is empty")]
    UndoStackEmpty,
    #[error("Document model didn't clean up properly on previous draw.")]
    ElementStackNonEmpty,
    #[error("DocumentModel modification failed: {0}")]
    DocumentModel(#[source] document_model::error::DocumentModelError),
    #[error(
        "Tried popping unexpected element: got root [{current_root:?}], exepected root: [{expected_root:?}]"
    )]
    InvalidElementPopped {
        current_root: DebugOf,
        expected_root: DebugOf,
    },
    #[error("Slicers went out of sync: {message}")]
    SlicersWentOutOfSync { message: String },
    #[error("Error occurred when reparenting: {source}")]
    Reparenting { source: RawOperationError },
    #[error("When reverting trailing mutations: {0}")]
    UndoingTrailingMutations(#[source] MutationError),
    #[error("When performing new mutations: {0}")]
    PerformingNewMutations(#[source] MutationError),
    #[error("This should never happen, but runtime crashed on previous redraw.")]
    RuntimeCrashedOnPreviousRedraw,
    #[error("Reinserting old child resulted in an error.")]
    ReinsertingOldChild(#[source] RawOperationError),
    #[error("Removing old child.")]
    RemovingElement(#[source] RawOperationError),
}

type RuntimeResult<T> = std::result::Result<T, RuntimeError>;

pub fn get_document() -> RuntimeResult<Document> {
    web_sys::window()
        .ok_or(RuntimeError::NoWindow)
        .and_then(|window| window.document().ok_or(RuntimeError::NoDocument))
}

#[derive(Debug)]
pub struct Runtime {
    pub dom_executor: DomExecutor,
}

impl Runtime {
    pub fn root_element(&self) -> &ElementId {
        self.dom_executor
            .executed
            .as_ref()
            .map(|executed| &executed.element.create.log.element_id)
            .expect("runtime crashed")
    }
    pub fn new(root_element: impl Into<Element>) -> Self {
        Self {
            dom_executor: DomExecutor::new(ElementId::new(root_element.into())),
        }
    }
}