[package] name = "flowrs-core" version.workspace = true edition.workspace = true publish.workspace = true rust-version.workspace = true authors.workspace = true license.workspace = true [lib] crate-type = ["cdylib", "rlib"] [dependencies] # The one implementation of sin, exp, ln, atan2, powf and the rest, the same bits in the # browser and in a generated program (crates/flowrs-math). flowrs-math = { path = "../flowrs-math" } # Serialization serde = { workspace = true } serde_json = { workspace = true } # ONNX runtime — tract is pure Rust and compiles to wasm32, so ONNX inference runs # in the browser with no JS runtime and no native build. Optional: native consumers # (flowrs-server, the CLI) do not pay for it unless they ask. tract-onnx = { version = "0.23.9", features = ["getrandom-js"], optional = true } # TinyML: a serde model schema + a dependency-free f32 inference/training runtime. # Pulled in so the ml widgets can TRAIN AND RUN a real network at T0 in the browser. # Its only transitive addition is `libm` (no_std math) — no model-runtime bulk. flowrs-ml = { path = "../flowrs-ml" } # DSP: the tested filter designers (Butterworth, Chebyshev I/II, elliptic, Bessel) and # zero-phase filtfilt behind the dsp.filter.iir widget — the standalone library made # reachable from the canvas. `default-features = false` keeps the dependency explicit. # `fft` is on so `dsp.pitch_to_note` and `dsp.detect_onsets` can call `note_of` and # `detect_onsets`; those functions live behind flowrs-dsp's fft feature (its own transform, on # flowrs-math, since rustfft's arithmetic followed the CPU). flowrs-dsp = { path = "../flowrs-dsp", default-features = false, features = ["fft"] } # Test records: the union `TestRun` and its seven format adapters (STDF, OpenHTF, # SystemLink, WATS, HardPy, OpenTAP, JUnit XML) behind the record.* widgets — the standalone # library made reachable from the canvas. Every adapter is a pure function over plain # data, so the browser produces the real report rather than a preview of one. Adds no # wasm weight: its whole tree is serde + serde_json + flowrs-sequence, all already here. flowrs-record = { path = "../flowrs-record" } # The test station `instrument.station` runs, at both tiers. flowrs-station = { path = "../flowrs-station" } # NI TDMS: a `data.tdms` node reads a channel from the browser's file store. flowrs-tdms = { path = "../flowrs-tdms" } # Logic and waveform captures (VCD/FST/GHW, sigrok, Saleae) and the protocol decoders # that run on them: `capture.open` reads a file from the browser's store and the # `decode.*` nodes add lanes. The same functions run in the generated program. flowrs-capture = { path = "../flowrs-capture" } # Instrument transports: the sans-IO SCPI/Red Pitaya/SiLA protocol layer behind the # instrument.* widgets. Because it owns no socket and no clock, its command building and # reply parsing are pure functions that run at T0 in the browser — which is what makes # those nodes live rather than codegen-only. It has ZERO dependencies, so the wasm bundle # grows by the protocol code and nothing else. flowrs-transport = { path = "../flowrs-transport" } # The instrument catalogue behind `instrument.supply`: the node composes its lines and its # safe state from a descriptor, and refuses what the descriptor refuses (its ranges, its # OVP ceiling), at both tiers. Pure data plus serde and sha2, and the editor already links # it, so the wasm bundle gains the handful of built-in descriptors and nothing else. flowrs-instruments = { path = "../flowrs-instruments" } # Cloud clients: the sans-IO Particle Device Cloud and Roboflow inference request # builders/response parsers behind the `cloud.*` widgets. Pure string work, so both # halves run at T0 in the browser. Its network code (reqwest/rumqttc/tokio) is behind # the non-default "live" feature *and* gated to non-wasm targets, so the wasm bundle # stays lean; the only transitive addition is `embedded-hal`, which is traits only. # `mavlink-model`: the mavlink.* nodes check their messages, fields, units and commands # against the same dialect model the generated bridge runs on (no `mavlink` crate, wasm too). flowrs-connect = { path = "../flowrs-connect", features = ["mavlink-model"] } # Live sources: the stream shape the live.* nodes read (serial telemetry, RTT channels, # sampled globals). Only the default, pure part — protocol code and the stream type, # serde + object + gimli + defmt-parser, all wasm-ready; no probe, no serial port. flowrs-live = { path = "../flowrs-live" } # The multichannel signal value (`Value::Timeseries`): samples with their sample rate, # channel names and units on `@[time, channel]`, the Arrow Signal schema's Rust form. # Schema-only (arrow-schema has no dependencies) plus serde, which is already here. flowrs-schemas = { path = "../flowrs-schemas", features = ["serde"] } # The hashed interface model: UCUM units, flowRS units and clock domains, which the wire # check compares (graph::quantity) and the unit.convert/clock.convert nodes convert. no_std # + alloc with sha2 as its one dependency, so the browser bundle gains little. flowrs-iface = { path = "../flowrs-iface" } # The board registry: the MCU targets bind a graph's UART, I2C and SPI buses and ADC # channels to a board's pins from it (`codegen::mcu::bind`). Plain data plus serde, and the # editor already links it, so the wasm bundle gains nothing; its native-only census # (flowrs-sim's board rows) adds embedded-hal, which flowrs-connect already brings. flowrs-boards = { path = "../flowrs-boards" } # The one seatbelt policy + rlimits every compile and run for a visitor goes through: the # agent's checker here, and the forge and PIL that reuse it. Native-only work (the browser's # InBrowser toolchain runs none of it), but it compiles everywhere flowrs-core does — its # only non-std dependency, libc, is itself unix-gated. flowrs-sandbox = { path = "../flowrs-sandbox" } # String manipulation indexmap = "2.14.0" # Rust parsing + AST-anchored codegen (the `rir` IR: graph <-> syn AST). # "printing" enables ToTokens on syn's AST types (needed to re-emit the IR); # prettyplease formats the generated syn::File back to readable Rust. syn = { version = "3.0.9", features = ["full", "parsing", "printing", "visit", "extra-traits"] } quote = "1.0.46" proc-macro2 = "1.0.106" prettyplease = "0.3.0" # Taint tracking (graph::taint): the digests a release of a neural output is bound to. sha2 = { version = "0.11", default-features = false } [dev-dependencies] regex-lite = "0.1.9" # work/provenance: the Agent Trace export is validated against the specification's own # schema (tests/fixtures/agent-trace) by an independent validator, MIT; no network # (resolve-http off), and the fixture is pinned by its SHA-256. jsonschema = { version = "0.58.1", default-features = false } # tests/mavlink_nodes.rs: the mavlink.* nodes' generated programs against the vehicle twin # (`flowrs_connect::mavlink::peer`), and a ROS goal published to one, need the native # runtimes, which the library leaves out. flowrs-connect = { path = "../flowrs-connect", features = ["mavlink", "ros2"] } [features] default = [] # Pulls in the tract ONNX runtime — pure Rust, compiles to wasm32, so ONNX models # run in the browser. Enabled by flowrs-ui; native consumers do not pay for it. # `flowrs-ml/onnx` is the same gate for `infer_onnx` / `OnnxSession`, which # `ml.infer_onnx` calls. A build without this feature still compiles the widget. onnx = ["dep:tract-onnx", "flowrs-ml/onnx"] # `cfg(kani)` is set by `cargo kani`, never by cargo itself, so rustc does not know the # name. Declaring it keeps the proofs in `graph::widgets::dsp::proofs` from costing every # ordinary build a warning. [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)'] }