-
Notifications
You must be signed in to change notification settings - Fork 0
Experiment: Event Sourcing #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
4a21c13 to
26186e6
Compare
f9720e9 to
03a2adc
Compare
ea00522 to
06c83e2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Introduces an event-sourced “system/aggregate” approach for the desktop UI, refactoring intent handling into command transactions and aggregating layout/state updates centrally.
Changes:
- Added
DesktopSystem+ supportingCmd/Transactionprimitives to apply commands and update UI effects. - Refactored desktop/project/launcher interaction flow to return commands instead of
UserIntent. - Updated
massive_layoutAPI (padding and child/nesting naming) and broadened re-exports in a couple of modules.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| shell/src/application_context.rs | Small formatting-only change around animation cycle upgrade call. |
| layout/src/lib.rs | Switches to wildcard re-exports for layout public API. |
| layout/src/layouter.rs | Renames children → nested, updates builder API (padding), adds Thickness conversions, updates tests accordingly. |
| layout/src/dimensional_types.rs | Adds Thickness conversion from (Padding, Padding) and imports Padding from crate. |
| desktop/src/projects/project_presenter.rs | Introduces ProjectCommand; shifts presenter transitions to return Cmd and updates layout construction calls. |
| desktop/src/projects/project.rs | Splits LaunchGroup into properties + contents; introduces LaunchGroupProperties. |
| desktop/src/projects/mod.rs | Switches to wildcard re-exports for the projects module API. |
| desktop/src/projects/launcher_presenter.rs | Returns Cmd, emits DesktopCommand on launcher interactions, returns insertion index on present. |
| desktop/src/lib.rs | Adds new modules (aggregates, desktop_system, event_sourcing) and re-exports aggregates. |
| desktop/src/event_sourcing/mod.rs | Adds Cmd and Transaction primitives and composition ops for event-sourcing style updates. |
| desktop/src/desktop_system.rs | New DesktopSystem aggregate applying commands, managing hierarchy/layout specs, and updating effects. |
| desktop/src/desktop_presenter.rs | Refactors event forwarding to return Cmd; exposes apply_layout; adjusts layout building for nested. |
| desktop/src/desktop_interaction.rs | Replaces UserIntent with Cmd/DesktopCommand and updates keyboard preprocessing. |
| desktop/src/desktop.rs | Replaces presenter/interaction wiring with DesktopSystem and routes commands via transact + update_effects. |
| desktop/src/band_presenter.rs | Removes special-case “present primary instance”; returns insertion index; updates layout to use nested. |
| desktop/src/aggregates/ordered_hierarchy.rs | New ordered hierarchy aggregate with add/insert/remove and unit tests. |
| desktop/src/aggregates/mod.rs | New aggregates module exports. |
| desktop/src/aggregates/layout_specs.rs | New small Map wrapper with typed erroring remove and indexing. |
| .github/copilot-instructions.md | Adds guidance to prefer failing on unexpected states over silent defensive handling. |
|
|
||
| use derive_more::{From, Index, IndexMut, Into}; | ||
|
|
||
| use crate::Padding; |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This introduces a dependency from dimensional_types back to Padding (which appears to live in the layouter side), increasing module coupling in a place that otherwise looks like a low-level geometry/types module. Consider moving this From<(Padding, Padding)> for Thickness impl into layouter.rs (or colocating Padding with the other dimensional types) to keep dimensional_types independent of higher-level layout concerns.
| impl<const RANK: usize> From<(Padding<RANK>, Padding<RANK>)> for Thickness<RANK> { | ||
| fn from((leading, trailing): (Padding<RANK>, Padding<RANK>)) -> Self { | ||
| Self { | ||
| leading: leading.into(), | ||
| trailing: trailing.into(), | ||
| } | ||
| } | ||
| } |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This introduces a dependency from dimensional_types back to Padding (which appears to live in the layouter side), increasing module coupling in a place that otherwise looks like a low-level geometry/types module. Consider moving this From<(Padding, Padding)> for Thickness impl into layouter.rs (or colocating Padding with the other dimensional types) to keep dimensional_types independent of higher-level layout concerns.
| ProjectCommand::AddLauncher { | ||
| group, | ||
| id, | ||
| profile: _, | ||
| } => { | ||
| let target = DesktopTarget::Launcher(id); | ||
| self.hierarchy.add(group.into(), target.clone())?; | ||
| self.layout_specs | ||
| .insert_or_update(target, self.default_panel_size); | ||
| } |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The profile payload in ProjectCommand::AddLauncher is currently ignored (profile: _). That makes the command misleading as an event-sourcing primitive (it appears to carry the data required to apply the change, but the system drops it). Either remove profile from the command if it’s intentionally unused by the system state, or store/apply it (e.g., update the corresponding presenter/project aggregate) so replaying commands reconstructs all necessary state.
| #[allow(non_upper_case_globals)] | ||
| pub const None: Self = Self(Vec::new()); |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a non-UPPERCASE associated constant requires suppressing non_upper_case_globals, which is a sign the API is fighting Rust naming conventions. Consider replacing this with a conventional pub const NONE: Self = ... or a pub fn none() -> Self constructor to avoid the lint suppression while keeping call sites readable.
| #[allow(non_upper_case_globals)] | |
| pub const None: Self = Self(Vec::new()); | |
| pub const NONE: Self = Self(Vec::new()); |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
I suspect that the complexities of typed hierarchies is too much for me and there must be a simpler way. In this PR I took some inspiration from event sourcing to experiment with a systems / aggregate approach that - in the end - may result in a fully incremental system that is overall simpler to understand, easier to maintain, and supports adding cross-cutting features without to much accidental complexity.