Skip to content

Clip aggregate, parse-fidelity validation, trusted-edit perf path#203

Merged
fuzzzerd merged 10 commits intomasterfrom
fuzzz/clip-aggregate
Apr 29, 2026
Merged

Clip aggregate, parse-fidelity validation, trusted-edit perf path#203
fuzzzerd merged 10 commits intomasterfrom
fuzzz/clip-aggregate

Conversation

@fuzzzerd
Copy link
Copy Markdown
Owner

@fuzzzerd fuzzzerd commented Apr 28, 2026

Summary

Refactors the clip pipeline to a domain-owned aggregate with structured XML→domain parse-fidelity reporting.

  • `Clip` aggregate (`src/SharpFM.Model/Clip.cs`) — immutable, lazy-parsed; replaces `FileMakerClip` and evicts INPC from the model layer.
  • Strategy table (`src/SharpFM.Model/ClipTypes/`) — compile-time `ClipTypeRegistry.BuiltIns` array with one strategy per `Mac-XM*` format. Adding a new type is a single registration. Collapses the four-site dispatch called out in support additional FileMaker Mac-XM* clipboard types #187.
  • `ClipParseResult` / `ClipParseReport` / `ClipParseDiagnostic` (`src/SharpFM.Model/Parsing/`) — every parse produces a structured report classifying losses (`UnknownStep`, `UnknownStepElement`, `RoundTripValueMismatch`, `DroppedNamespace`, etc.) with XPath-style locations.
  • `XmlRoundTripDiff` substrate detects unmodeled XML by parse → re-serialize → structural diff, normalising attribute order, namespace prefixes, and whitespace before comparing.
  • Visible UX — status-bar parse-fidelity summary and a `!` glyph next to lossy clips in the tree.
  • `Clip.FromEditor` trusted-edit path — editor edits skip the strategy parse + diff entirely (the editor's model is the source of truth), avoiding the per-keystroke parse cost on large scripts.
  • `FmScript.ToElement` / `FmTable.ToElement` — additive APIs that let the strategies skip the parse-and-prettify round-trip on the diff path.
  • `ClipDataExtensions` routes through the registry — plugin-side dispatch consolidated with the host.

Out of scope (tracked in #202)

  • `ClipData.ParseReport` (carry the report on the plugin-boundary record).
  • `IPluginHost.ValidateClipXml` API.
  • Semantic-validation tier (e.g., FileMaker variable name format checks).
  • `Clip.Rename` consumer decision.

Test plan

  • `dotnet test SharpFM.sln` — 1315 green (1223 SharpFM.Tests + 92 SharpFM.Plugin.Tests).
  • Sibling `SharpFM.Productivity` builds and tests pass against this branch.
  • Manual: paste a clip with unmodeled attributes from FileMaker; confirm status bar shows the diagnostic count and the tree node carries the `!` glyph.
  • Manual: edit a large (~500-step) script; confirm typing is responsive (trusted-edit path skips parse/diff per keystroke).

fuzzzerd added 10 commits April 28, 2026 08:30
- Editors expose GetModel() so the aggregate can take their parsed
  state directly. ClipViewModel.HandleEditorContentChanged routes
  through Clip.FromEditor which wraps the model in ParseSuccess
  without running the strategy or the round-trip diff. Per-keystroke
  cost on a 1000-step script drops from ~500ms-2.5s of XML work to
  the editor's own re-render.
- FmScript.ToElement / FmTable.ToElement skip the parse-and-prettify
  round-trip strategies were doing on the diff path.
- ClipDataExtensions routes through the registry instead of calling
  FmScript.FromXml / FmTable.FromXml directly so plugin-side parsing
  shares the host's dispatch.
- ClipTypeRegistry collapses to an immutable static array. No
  Register, RegisterBuiltIns, Reset, no _initialized flag, no test
  isolation collection — clip strategies are fully owned by SharpFM
  and known at compile time.
@github-actions
Copy link
Copy Markdown

Test Results

✔️ Tests 1315 / 1315 - passed in 15.8s
✔️ Coverage 78.75% - passed with 70% threshold
📏 14728 / 17174 lines covered 🌿 4952 / 7816 branches covered
🔍 click here for more details

✏️ updated for commit e078625

@fuzzzerd fuzzzerd merged commit eba95cf into master Apr 29, 2026
6 checks passed
@fuzzzerd fuzzzerd deleted the fuzzz/clip-aggregate branch April 29, 2026 02:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant