Skip to content

StorageScope v0.5.0 — Search + Performance Upgrade

Choose a tag to compare

@RasputinKaiser RasputinKaiser released this 22 Jun 03:37

v0.5.0 — Search + Performance Upgrade

15 PRs since v0.4.5 (#75#89). All backwards-compatible additions; no breaking API changes. The cumulative story is the search bar becoming a real Mac-app search surface (multi-word AND, find-next, recents, badge, empty states) plus the first round of scan-phase performance work (signpost instrumentation, derived-cache reuse, background-persisted disk writes).

Search

  • Multi-word AND search with path-segment matching + substring highlight (#84) — queries split on whitespace and require every term to match. Terms also match against /-split path segments, so Documents report matches both Documents as a path segment AND report as a substring of name. Matched substrings render in accent color via a new HighlightedText SwiftUI view struct (file list + Folder Tree).
  • Search-result count badge (#86) — pill-shaped N matches badge in StorageItemTable header when a search is active. Distinguishes nil (no search) from zero matches so the empty-state view can tell them apart.
  • Search-empty vs filter-empty distinction (#87) — FilterRecoveryView now distinguishes noScan, noMatches (search active, zero hits), and filteredEmpty (filter chips, zero hits) with state-appropriate iconography and copy.
  • Cmd+G find-next navigation (#88) — Mail/Finder convention. Cmd+G advances through search-result rows and wraps around; Cmd+Shift+G reverses. Sets selectedItemID so the matched row takes focus. Menu items gate on search-active.
  • Search recents persistence (#89) — SearchRecentsStore mirrors the RecentsStore ring-buffer pattern; recent terms surface as .searchSuggestions on the search field with Clear Recents. Persists across launches via UserDefaults.

Performance

  • os_signpost instrumentation on scan phases (#81) — enumerate, verify, persist, and index spans wrap the hot paths so Instruments → Points of Interest can profile. Zero behavioral change — no-ops when no profiler is attached.
  • Cache duplicateGroups + verifiedDuplicateGroups per scanFinishedAt (#79) — mirrors the existing cleanupCandidates cache pattern. Avoids re-walking size-group / verified-group aggregation on every Duplicate Review view transition.
  • Background-persist RecentsStore writes off the main actor (#80) — heavy JSON encode + UserDefaults write detaches to .utility priority; @Published entries still updates synchronously so SwiftUI sees immediate change. Matches the v0.3.0 hashCache.persist() pattern.
  • Extend ScanBenchmarkReport with per-phase durations (#83) — enumerateDuration, verifyDuration, persistDuration, and totalDuration computed property. duplicateVerificationDuration kept as deprecated alias for backward compat.

UI / chrome

  • File → Open Recent submenu (#82, bonus) — mirrors macOS convention for non-document apps: lists recently-scanned folder paths so users can re-launch a scan without reaching for the sidebar. Dynamic rebuild on each menu open via NSMenuDelegate; gates on !store.isScanning.
  • keyboard-shortcuts.html docs page (#76) — documents every v0.4.5 + v0.5.0 hotkey (Cmd+G/Cmd+Shift+G originally listed as "Coming in v0.5.0"; now shipping).
  • architecture.html docs page (#75) — documents the ScanStore tier-2 sub-store extraction pattern + filterBinding bridge + derived cache invalidation, with an ASCII store-hierarchy diagram.
  • Cross-page version bump to v0.4.5 (#77, #78) — index landing page What's new ticker + cross-page nav links bumped to v0.4.5 (carried forward to v0.5.0 in the prep PR).
  • Expand changelog with v0.4.5 subsections + v0.4.0 release (#85) — backfilled the full v0.4.5 section structure (Sidebar / Item rows / Trash review / Mac menu / Overview-Inspector / Refactors / Accessibility) and the v0.4.0 release section so the changelog reads as a contiguous history.

Validation

  • swift test — 90 tests across 10 suites pass
  • plutil -lint Config/StorageScope.entitlements Resources/PrivacyInfo.xcprivacy — clean
  • bash -n across all scripts — clean
  • ./script/public_upload_audit.sh — passes
  • DMG: exports/StorageScope-0.5.0.dmg, SHA256 09691b50ca0c60318a5f3544fcb8fa1a3f44007843188a8e348f2080ac9fb871hdiutil verify confirmed

Why v0.5.0 (not v0.4.6)

Per semver: pre-1.0 minor is the standard "feature-bearing release" bump. v0.5.0 ships the second major UX arc (search) — a meaningful feature surface, not a patch on v0.4.5's polish work. The 15 PRs are all backwards-compatible additions; no breaking API changes to FileSystemScanner.scan(...) or ScanStore's public surface.

Deferred

  • Tier 3 SelectionState / Tier 4 TrashReviewState extractions — still pending; same lazy-var + closure-injection template from v0.4.5 Tiers 1-2.
  • Tier 5 @Observable macro migration — still blocked by didSet observers on tracked properties (deferred to v1.0.0).
  • Sparkle 2.x auto-update — still gated on notarization (PR #19's script/notarize_dmg.sh scaffolding from v0.4.0 waits on Apple Developer ID credentials).