|
|
Donner SVG 0.8.0-pre
SVG editor and embeddable C++20 engine.
|
Data model for a .donner-repro file: a recorded sequence of editor UI inputs (mouse events, keyboard events, wheel events, window resizes) plus enough session metadata to re-instantiate the editor and replay the events deterministically. More...
#include <cstddef>#include <cstdint>#include <filesystem>#include <optional>#include <string>#include <string_view>#include <vector>Classes | |
| struct | donner::editor::repro::ReproViewport |
| Snapshot of the editor viewport used to map window coordinates into SVG-document coordinates. More... | |
| struct | donner::editor::repro::ReproHit |
| Hit-test checkpoint captured at mouse-down time. More... | |
| struct | donner::editor::repro::ReproAction |
| One semantic editor action that fired within a frame. MCP-generated repros use actions for deterministic operations that are not raw pointer input, such as selecting the Pen tool or changing active paint. More... | |
| struct | donner::editor::repro::ReproEvent |
| One discrete event that fired within a frame. Frame-state (mouse position, button mask) lives on the owning frame record; this captures only events that can't be reconstructed from continuous state (key presses, character input, wheel deltas, resizes). More... | |
| struct | donner::editor::repro::ReproFrame |
| One frame's snapshot: continuous input state + any discrete events that fired during the frame. More... | |
| struct | donner::editor::repro::ReproExpectedCrop |
| Optional pixel crop attached to a replay expectation. More... | |
| struct | donner::editor::repro::ReproExpectation |
| Human-reviewed expectation metadata for important replay fixtures. More... | |
| struct | donner::editor::repro::ReproMetadata |
| Session-level metadata captured at recording start. More... | |
| struct | donner::editor::repro::ReproFile |
| In-memory form of a loaded or in-progress recording. More... | |
| struct | donner::editor::repro::ReproReplaySecurityPolicy |
| Ambient capabilities granted while replaying an untrusted recording. More... | |
| struct | donner::editor::repro::ReproSvgFile |
| SVG source loaded from a replay-relative path. More... | |
Namespaces | |
| namespace | donner |
| Top-level Donner namespace, which is split into different sub-namespaces such as donner::svg and donner::css. | |
Enumerations | |
| enum class | donner::editor::repro::ReproExpectationProofKind { PresentedPixels , ActiveDragAlignment , Selection , WorkerLiveness } |
| What a curated replay fixture is expected to prove. | |
Functions | |
| std::string | donner::editor::repro::ReproSvgDisplayName (const ReproMetadata &metadata) |
| Return a bounded display-only name for replay SVG metadata without constructing a native path. | |
| bool | donner::editor::repro::IsSafeReproSvgPath (std::string_view path) |
| Returns whether a recorded SVG path is a safe replay-directory-relative path. | |
| std::optional< ReproSvgFile > | donner::editor::repro::ReadReproSvgFile (const std::filesystem::path &rnrPath, std::string_view recordedSvgPath) |
| Read a recorded SVG through a descriptor-rooted sandbox beneath the replay directory. | |
| bool | donner::editor::repro::WriteReproFile (const std::filesystem::path &path, const ReproFile &file) |
| Serialize file to the given path in NDJSON form. Returns true on success; on failure writes an error message to stderr and returns false. Atomic: writes to path.tmp then renames over path, so a crash mid-write never truncates an existing file. | |
| std::optional< ReproFile > | donner::editor::repro::ParseReproFile (std::string_view contents) |
| Parse an in-memory NDJSON repro document. | |
| std::optional< ReproFile > | donner::editor::repro::ReadReproFile (const std::filesystem::path &path) |
| Parse an NDJSON repro file. Returns std::nullopt on any error (file missing, version mismatch, malformed line); writes details to stderr. When reading a v1 file, the v2-only fields stay default-constructed. | |
Variables | |
| constexpr int | donner::editor::repro::kReproFileVersion = 4 |
| File format version written by the current serializer. | |
| constexpr size_t | donner::editor::repro::kMaximumReproFileSize = 64 * 1024 * 1024 |
| Maximum accepted .donner-repro file size. | |
| constexpr size_t | donner::editor::repro::kMaximumReproMetadataLineBytes = 32 * 1024 * 1024 |
| Maximum accepted metadata-line size, including an embedded SVG snapshot. | |
| constexpr size_t | donner::editor::repro::kMaximumReproFrameLineBytes = 2 * 1024 * 1024 |
| Maximum accepted frame-line size. | |
| constexpr size_t | donner::editor::repro::kMaximumReproActionPropertyValueBytes = 64 * 1024 |
| Maximum decoded bytes accepted for one semantic action property value. | |
| constexpr size_t | donner::editor::repro::kMaximumReproRetainedStringBytes = 24 * 1024 * 1024 |
| Maximum aggregate decoded string bytes accepted while parsing one replay. | |
| constexpr size_t | donner::editor::repro::kMaximumReproScanWorkBytes = 128 * 1024 * 1024 |
| Maximum aggregate structural scan work accepted while parsing one replay. | |
| constexpr size_t | donner::editor::repro::kMaximumReproFrames = 10'000 |
| Maximum number of frames accepted from one replay file. | |
| constexpr size_t | donner::editor::repro::kMaximumReproPlaybackFrames = 1'024 |
| Maximum number of frames that one untrusted replay may execute. | |
| constexpr size_t | donner::editor::repro::kMaximumReproPixelFrames = 128 * 1024 * 1024 |
| Maximum aggregate physical-pixel frames that one replay may request. | |
| constexpr size_t | donner::editor::repro::kMaximumParsedReproPixelFrames = 8ULL * 1024 * 1024 * 1024 |
| Maximum aggregate physical-pixel frame metadata accepted while parsing one replay. | |
| constexpr size_t | donner::editor::repro::kMaximumReproItemsPerFrame = 1'024 |
| Maximum number of actions or events accepted in one frame. | |
| constexpr size_t | donner::editor::repro::kMaximumReproItems = 100'000 |
| Maximum combined number of actions and events accepted from one replay file. | |
| constexpr int | donner::editor::repro::kMaximumReproDimension = 8'192 |
| Maximum accepted logical window dimension in replay metadata and resize events. | |
| constexpr int | donner::editor::repro::kMaximumReproPixelDimension = 8'192 |
| Maximum accepted physical-pixel dimension derived from replay metadata. | |
| constexpr size_t | donner::editor::repro::kMaximumReproPixels = 16 * 1024 * 1024 |
| Maximum accepted physical-pixel area derived from replay metadata (64 MiB RGBA). | |
| constexpr double | donner::editor::repro::kMaximumReproDevicePixelRatio = 4.0 |
| Maximum accepted device-pixel ratio in replay metadata and viewport snapshots. | |
| constexpr double | donner::editor::repro::kMaximumReproDurationSeconds = 30.0 |
| Maximum accepted duration of a paced replay. | |
| constexpr double | donner::editor::repro::kMaximumReproDeltaMilliseconds = 5'000.0 |
| Maximum accepted time step for one replay frame. | |
| constexpr int | donner::editor::repro::kMaxMouseButtons = 5 |
| Maximum number of mouse buttons recorded. Matches ImGui's ImGuiMouseButton_COUNT. | |
| constexpr ReproReplaySecurityPolicy | donner::editor::repro::kUntrustedReproReplaySecurityPolicy {} |
| Security policy applied by all untrusted replay entry points. | |
| constexpr std::size_t | donner::editor::repro::kMaximumReproSvgPathBytes = 4096 |
| Maximum byte length accepted for a replay-relative SVG path. | |
| constexpr std::size_t | donner::editor::repro::kMaximumReproSvgPathComponents = 256 |
| Maximum number of components accepted for a replay-relative SVG path. | |
Data model for a .donner-repro file: a recorded sequence of editor UI inputs (mouse events, keyboard events, wheel events, window resizes) plus enough session metadata to re-instantiate the editor and replay the events deterministically.
The file records at the raw ImGui-input level (below menu action dispatch, below tool dispatch, below the compositor) so every stage of the stack - from Donner's DOM mutations down through the RendererTinySkia pixel ops - is exercised during playback. That breadth is the point: a recording made in the live editor reproduces the bug regardless of which layer it lives in.
Format is one JSON object per line (NDJSON):
Frame records carry the full mouse state plus any discrete events that fired during that frame. Discrete events are keyed by short type codes:
| code | meaning | fields |
|---|---|---|
| mdown | mouse button down | b (button index 0-4), hit{} |
| mup | mouse button up | b |
| kdown | keyboard key down | k (ImGui key enum), m (mods) |
| kup | keyboard key up | k, m |
| chr | character input | c (UTF-32 code point) |
| wheel | mouse wheel | dx, dy (float units) |
| resize | window resize | w, h |
| focus | window focus change | on (0/1) |
The "frame record" itself captures the continuous state (mouse position + current button mask) so a dropped event in the discrete list can't leave the player in an inconsistent state - the next frame's state trumps.
Since v2 the frame record can also carry:
Since v3 the metadata line can also carry a deterministic snapshot of the initial SVG source:
Since v4 frame records can also carry semantic editor actions:
|
nodiscard |
Returns whether a recorded SVG path is a safe replay-directory-relative path.
Absolute paths, empty paths, and any parent-directory component are rejected. This validation is also applied while parsing legacy replay metadata that lacks an embedded SVG snapshot.
| path | Recorded path from replay metadata. |
|
nodiscard |
Read a recorded SVG through a descriptor-rooted sandbox beneath the replay directory.
Symlinks and other filesystem objects that could escape or block the read are rejected. Explicit caller-supplied SVG overrides do not use this function and remain unrestricted.
| rnrPath | Path to the replay file. |
| recordedSvgPath | Replay metadata path, relative to the replay directory. |
|
nodiscard |
Return a bounded display-only name for replay SVG metadata without constructing a native path.
Directory components, absolute roots, invalid UTF-8, and embedded NULs are discarded. The returned value is informational only and must not be used as a current/save path.
|
constexpr |
Maximum aggregate physical-pixel frame metadata accepted while parsing one replay.
Parsing does not allocate a surface per frame. This larger, still finite ceiling preserves compatibility with archived recordings that callers compact before playback; execution always enforces the stricter kMaximumReproPixelFrames limit.
|
constexpr |
File format version written by the current serializer.
The reader accepts: