Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/nornir-saga/Cargo.toml

[package]
name = "nornir-saga"
version = "0.2.0"
edition = "2021"
description = "Saga — capture a user's navigation (nav/click/log) as structured events, persist them to the nornir warehouse, and let the test matrix REPLAY the path as a generated robot test for bug-finding + regression. The production sibling of nornir-testmatrix: emit real state from inside → warehouse → read back. Toolkit-neutral core (pure std + serde — no eframe/leptos/iceberg)."
license = "MIT OR Apache-2.0"
repository = "https://git.gunnar.rs/nordisk/edda"
readme = "README.md"
keywords = ["navigation", "replay", "telemetry", "testing", "egui"]
categories = ["development-tools::testing", "web-programming"]
# Keep the published crate lean: the .nornir design/runtime dir is not part of
# the library.
exclude = [
    "/.nornir/",
    "docs/book.pdf",
]

[dependencies]
# The LEAN CORE deps — the crate stays heavy-dep-free by default (no eframe/
# leptos/iceberg/arrow) so any frontend (egui app OR web app) pulls it cheaply.
# The web frontend (axum + SSE) and the real-browser driver (fantoccini) are
# OPTIONAL, behind the `web` / `drive` features — a default build carries neither.
serde = { version = "1", features = ["derive"] }
# `float_roundtrip`: parse f64 with full precision so a persisted saga reloads
# byte-for-byte. Deterministic replay is a contract promise — a saga written to
# JSON and read back must fold to the identical model (cursor coords are f64), so
# the default 1-ULP-lossy float parser is not acceptable here.
serde_json = { version = "1", features = ["float_roundtrip"] }
anyhow = "1"

# Web frontend (feature `web`): axum router + SSE, tokio runtime, stream adapter.
# Mirrors the knut-pipelines `web` viewer pattern. OFF by default.
axum = { version = "0.8", optional = true }
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "net", "time"], optional = true }
tokio-stream = { version = "0.1", features = ["sync"], optional = true }
futures-util = { version = "0.3", optional = true }

# Real-browser replay driver (feature `drive`): a WebDriver client + a runtime to
# block on it. OFF by default — no browser/async deps in a normal build.
fantoccini = { version = "0.22", optional = true }

# Test-matrix emit MODE (feature `testmatrix`): pull `nornir-testmatrix` so a
# saga replay's verification records honest `functional_status` matrix rows
# (step-success / step-fail / rollback). OFF by default — a release strips every
# emit to an `#[inline]` no-op and does NOT link `nornir-testmatrix`.
nornir-testmatrix = { version = "0.2.7", path = "../nornir-testmatrix", optional = true }
# Bench MODE (feature `bench`): register the replay-fold bencher (the hot
# execution path) with the `nornir-bench` harness. OFF by default.
nornir-bench = { version = "0.2.0", path = "../nornir-bench", optional = true }

[dev-dependencies]
# `web`-feature tests drive the axum router as a test client (`oneshot`) and
# collect the response bodies — same pattern as knut-pipelines.
tower = { version = "0.5", features = ["util"] }
http-body-util = "0.1"

[features]
# `saga` — the CAPTURE MODE (BOTH the navigation `record()` buffer AND the
# UI-movement `ui::tap`/`ui::capture` buffer). DEV-ONLY, off by default: when ON,
# capture stamps + buffers events; when OFF, every emit hook is an `#[inline]`
# no-op and the buffers compile to nothing (pure std — ZERO extra deps either
# way). A consuming app takes `nornir-saga` as an optional dep behind its own
# off-by-default `saga` feature and taps its Elm `update`; `cargo run --features
# saga` captures, `cargo build --release` ships clean. See `.nornir/saga-*.md`.
default = []
saga = []
# `web` — the axum + SSE viewer/replay frontend (`ui::web`). Demoable with a
# synthetic saga, no live Njord. OFF by default (keeps the core lean).
web = ["dep:axum", "dep:tokio", "dep:tokio-stream", "dep:futures-util"]
# `drive` — the real-browser `WebReplayDriver` (`ui::driver::webdriver`) over
# WebDriver (fantoccini). OFF by default; needs a running geckodriver/chromedriver.
drive = ["dep:fantoccini", "dep:tokio"]
# `testmatrix` — light the replay-verification `functional_status` emits
# ([`ui::Player::verify`]). OFF by default (release links no matrix dep).
testmatrix = ["dep:nornir-testmatrix", "nornir-testmatrix/testmatrix"]
# `bench` — register the replay-fold `Bencher` (`bench`) with `nornir-bench`.
bench = ["dep:nornir-bench"]