From 602145c956bb594ca0d0e10601cc4ad1a71cf70d Mon Sep 17 00:00:00 2001 From: Josh Kingsley Date: Sun, 23 Nov 2025 19:27:57 +0200 Subject: feat: integrate web and doc packages --- packages/doc/src/lib.rs | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 packages/doc/src/lib.rs (limited to 'packages/doc/src/lib.rs') diff --git a/packages/doc/src/lib.rs b/packages/doc/src/lib.rs new file mode 100644 index 0000000..a1d7497 --- /dev/null +++ b/packages/doc/src/lib.rs @@ -0,0 +1,97 @@ +use thiserror::Error; +use uuid::Uuid; +use wasm_bindgen::prelude::*; + +use crate::{ + doc::{ApplyOpError, Doc}, + op::{CreateGrid, Op, OpKind}, + vector_clock::VectorClock, +}; + +mod doc; +mod op; +mod vector_clock; + +#[derive(Error, Debug)] +pub enum Error { + #[error("error while realizing state")] + RealizeError(#[from] ApplyOpError), +} + +#[wasm_bindgen] +pub struct State { + actor_id: Uuid, + ops: Vec, +} + +#[wasm_bindgen] +impl State { + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + let actor_id = Uuid::now_v7(); + + Self { + actor_id, + ops: vec![], + } + } + + pub fn create_grid(&mut self) { + self.append_op(OpKind::CreateGrid(CreateGrid { + rows: 4, + base_cells_per_row: 16, + })); + } + + pub fn to_json(&self) -> JsValue { + let doc = self.realize().unwrap(); + serde_wasm_bindgen::to_value(&doc).unwrap() + } +} + +impl State { + pub fn append_op(&mut self, kind: OpKind) { + let clock = self + .ops + .last() + .map(|op| op.clock.inc(&self.actor_id)) + .unwrap_or_else(|| VectorClock::new().inc(&self.actor_id)); + + self.ops.push(Op { + id: Uuid::now_v7(), + clock, + kind, + }); + } + + pub fn realize(&self) -> Result { + let mut doc = Doc::default(); + + for op in &self.ops { + doc.apply_op(op)?; + } + + Ok(doc) + } +} + +#[cfg(test)] +mod tests { + use crate::op::CreateGrid; + + use super::*; + + #[test] + fn test() { + let mut state = State::new(); + + state.append_op(OpKind::CreateGrid(CreateGrid { + rows: 4, + base_cells_per_row: 16, + })); + + let doc = state.realize().unwrap(); + let grid = doc.grids.first().unwrap(); + assert_eq!(grid.rows.len(), 4); + } +} -- cgit v1.2.3