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

nordisk/knut

crates/knut-popviz/Cargo.toml

[package]
name = "knut-popviz"
description = "egui driver for the population bulk-loader — live progress + headless introspection"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
# Development notes, agent instructions and machine-local tooling stay in the
# repository; they are not part of the published crate.
exclude = [
    ".nornir/",
]

[features]
default = []
# The desktop egui driver. Off by default so the lib (population gen + the
# introspectable state) builds + tests headlessly without a GUI stack. The
# desktop app folds in `autostart` so the UI just-works against a fresh DB.
gui = ["dep:eframe", "dep:egui", "dep:facett-pop", "autostart"]
# FalkorDB autostart — when the configured `--url` is unreachable, bring up a
# FalkorDB container from Rust (testcontainers → Podman, LAW 7) and connect to
# it. Pulls testcontainers/Podman via graphar-falkordb, so it's behind a feature
# (folded into `gui`); the lean default build does not pull it.
autostart = ["graphar-falkordb/autostart"]
# Iceberg target — load the simulated population into an Iceberg warehouse
# (one table per label) beside the FalkorDB target. Pulls the `skade`
# (arrow-59/iceberg) tree, so it's opt-in.
iceberg = ["dep:skade", "dep:arrow-select"]
# The Iceberg target through an Iceberg REST catalog - MinIO AIStor `/_iceberg` with SigV4
# `s3tables`, Nessie, Polaris (`knut-popload --rest-uri`). See src/lake.rs.
iceberg-rest = ["iceberg", "skade/rest-catalog"]
# `testmatrix` — emit the bulk-loader's health (`run_load` outcome) into the
# nornir test-matrix via `functional_status`. OFF BY DEFAULT: a compiled-out
# `#[inline]` no-op with no nornir dep.
testmatrix = ["dep:nornir-testmatrix", "nornir-testmatrix/testmatrix"]

[lib]
name = "knut_popviz"
path = "src/lib.rs"

[[bin]]
name = "knut-popviz"
path = "src/main.rs"
required-features = ["gui"]

# The same load, headless - no GUI stack: what a "Simulate" press runs on a FalkorDB host.
[[bin]]
name = "knut-popload"
path = "src/bin/knut-popload.rs"

[dependencies]
# The canonical pure-Rust population model (LABELS, geo placement, PopGraph) —
# shared with the facett demo. The Arrow → FalkorDB/Iceberg load path below
# stays here in popviz.
knut-popsim = { path = "../knut-popsim" , version = "0.3.0" }
graphar-falkordb = { path = "../graphar-falkordb" , version = "0.3.0" }
# The Iceberg target's permutate (feature `iceberg`): Spark-style copy-on-write rounds -
# skade's Table::overwrite over live_data_files, and arrow's row filter.
skade = { version = "0.7.0", default-features = false, optional = true }
arrow-select = { version = "59", optional = true }
# Introspection-marker emitter — only compiled with `testmatrix`.
nornir-testmatrix = { version = "0.2", default-features = false, optional = true }
arrow-array = { workspace = true }
arrow-schema = { workspace = true }
tokio = { workspace = true }
serde_json = { workspace = true }
# Parallel synthetic batch-generation (the "sim") — the pure-CPU vertex/edge Arrow
# gen fans across all cores instead of one (the biggest single-core chunk of the
# ingest path), ahead of the concurrent insert. LAW: concurrency → gatling
# (znippy-zoomies), NEVER rayon/thread::spawn.
# From crates.io: a `path` three levels above the repo root aborts resolution
# for the whole workspace on a bare clone, even though the version is published.
znippy-zoomies = { version = "0.1.20" }

# Desktop GUI stack — only with `gui`, egui 0.34 (matches facett-pop). knut-pipelines' snarl gui stays 0.28 (unused by korp; snarl 0.4→0.9 deferred).
#
# LAW #4 — WebGPU, never WebGL/OpenGL. `wgpu`, NOT `glow`: eframe resolves
# `Renderer::default()` to `Glow` whenever its `glow` feature is on (eframe 0.34.3
# `epi.rs`), and `main.rs` passes a bare `NativeOptions::default()` — so while `glow`
# was listed here the SHIPPED desktop binary rendered on OpenGL, with `glow v0.17`
# linked in twice (directly and via `egui_glow`). Measured: both of those edges are
# gone, and the only `glow` left in the graph is `wgpu-hal`'s internal GLES backend,
# which is a separate thing and not a violation.
#
# `default_fonts` matches every other eframe line in the fleet (facett-pipeline,
# facett-cicd, facett-demo, …), which is where this incantation comes from; popviz was
# getting fonts transitively through its plain `egui` dep. `wayland`/`x11` fan out to
# `egui-wgpu?/wayland` and `egui-wgpu?/x11`, so they keep working unchanged.
#
# No source change is needed or wanted: the renderer is chosen by the feature, so the
# backend flips underneath the one `run_native` call. Dropping BOTH backends is a
# `compile_error!` in eframe, so the swap has to be one edit — it is.
# Guarded by `tests/law4_no_opengl_backend.rs`.
eframe = { version = "0.36", default-features = false, features = ["default_fonts", "wgpu", "wayland", "x11"], optional = true }
egui = { version = "0.36", optional = true }
# Shared visual components — the progress bars come from facett-pop (cut-over).
facett-pop = { optional = true , version = ">=0.1.9, <0.3" }

[dev-dependencies]
# tests/sim_iceberg_falkordb.rs: the Iceberg target and permutate, read by bifrost with
# each of mappings/population.{yml,json,sql}, into a real FalkorDB.
knut-bifrost = { path = "../knut-bifrost", features = ["skade", "skade-rest", "sql"] }
testcontainers = "0.27"
tokio = { workspace = true }
# Container-free Iceberg-target robot test: a scratch warehouse dir that
# auto-cleans, so `run_load` can be driven end-to-end with no DB (`iceberg`).
tempfile = "3"
# The live FalkorDB bulk↔UNWIND byte-parity test (`--features autostart`,
# `#[ignore]`) reads back graphs via `FalkorDbLoader::run_query`, whose reply is
# a `redis::Value`; match graphar-falkordb's redis version so the types unify.
redis = { workspace = true }

# Headless robot-UI harness for the REAL popviz widget tree (`--features gui`).
# Same egui 0.34 / egui_kittest 0.34 stack facett's robot suites use (LAW 5 —
# one harness pattern across the fleet), wgpu backend for the pixel legs.
# LAW 4: wgpu, never a GL/WebGL path.
egui_kittest = { version = "0.36", default-features = false, features = ["wgpu"] }
egui = { version = "0.36" }
# Only to read back the rendered frame (RgbaImage) and write the PNG blobs;
# default features would drag the whole AVIF/AV1 encoder tree into the lock.
image = { version = "0.25", default-features = false, features = ["png"] }