Repository navigation
Description
Task
Consolidate stackpress-framework-preferences into stackpress-framework-view, organized as explicit presentation modules with optional host integrations. Preserve framework-ui as the Leptos rendering/component layer.
The owner accepted this direction on 2026-10-28. The goal is a coherent view feature that can include preferences, public flash notices and action-display integration without requiring every consumer to enable persistence or native storage. Renaming the existing bundle to framework-presentation was considered; consolidation into view is the selected direction.
Related: #14 defines the broader function-based framework plugin integration task. This issue specifies the presentation ownership/dependency change; coordinate entry-point naming with #14 rather than implementing competing plugin systems. Its example references to a separate preferences crate should be adapted to this consolidation.
Current behavior and source evidence
Baseline: remote trial/3 at 74319ac366f3397b684ee5fa8007651c19e54292. The cited preferences/language/view sources match the inspected local checkout.
- Preferences exports combine settings/actions, save state, flash, action-policy helpers and optional native file storage.
- View manifest currently defines a client-safe page-contract library with optional server integration.
- Preferences manifest depends on both language and view.
- Language manifest depends on view; its source imports
BasePathandPublicLocation. - HostAccess performs authoritative, fail-closed admission as well as public action projection. Moving it must preserve both contracts.
- Native file storage has explicit ownership/bounds and fixed persistent identities. Moving Rust modules must not reset saved settings.
Current dependencies:
framework-preferences → framework-language → framework-view
└────────────────────→ framework-view
framework-ui ──────────────────────────────→ framework-view
Moving preferences unchanged would introduce an invalid view → language → view cycle. Resolve that boundary before consolidation.
Intended organization
Illustrative module layout; final names and feature boundaries need a design checkpoint:
framework-view
├── page / routes # Public page/render/location contracts
├── preferences # Locale/theme values, updates and save state
├── flash # Bounded public notices
├── access # Public action hints and host-policy integration
└── adapters
├── web # Optional cookie/settings host integration
└── native # Optional installed-app settings storage
framework-ui # Leptos renderers, components and reactive contexts
Illustrative import migration — proposed API, not available today:
// Before:
use stackpress_framework_preferences::{Preferences, PreferenceState, ThemePreference};
// After:
use stackpress_framework_view::preferences::{
Preferences, PreferenceState, ThemePreference,
};A crate boundary does not have to equal a plugin boundary. Keep pages available with fixed settings while remembered preferences can be omitted:
// Proposed entry points; ordinary existing ServerBuilder selection.
app.plugin("views", framework_view::plugin::register)?;
#[cfg(feature = "remember-display-settings")]
app.plugin(
"view-preferences",
framework_view::preferences::register,
)?;Use PluginSpec dependency declarations where the reviewed contract identifies a real prerequisite.
Required behavior and boundaries
- Browser-safe contracts/helpers remain usable without a Server, native filesystem, Tauri or database.
- Native file persistence and host registration are opt-in. Shared UI consumes public values through adapters; it does not gain filesystem or arbitrary IPC access.
- Public allowed-action hints control display only. Authoritative admission remains at the protected operation boundary; disabling view/preferences/flash functionality must never bypass it.
- Cargo feature selection controls compiled code/dependencies; explicit plugin selection controls registered services/handlers/routes. Library import or feature enablement alone must not register effects.
- Plugin disablement follows the established rebuild/redeploy contract. Omission does not delete cookies, files or other stored settings.
- Preserve HTTP/Tauri reply formats, cookie names/scope/lifetimes, locale precedence, native file name/revision, cancellation/failure handling and unsaved drafts.
- No visual redesign, automatic migration/seed/listener startup, new auth system or expanded platform support is requested.
Acceptance criteria
- Freeze the ownership/module/API/feature plan, including the acyclic locale/view dependency strategy and changes to existing language APIs.
- Move the selected preferences/flash/access functionality into view without duplicating implementations. UI remains the Leptos layer.
- Preserve minimal default/browser graphs and optional native/host integration; demonstrate rendering with fixed settings and no preference persistence.
- Provide ordinary plugin-facing integration consistent with Expose framework features through ordinary Stackpress plugin registration #14; document configuration, policies, route/command exposure and real dependencies.
- Prove omitted preference/flash integrations add no corresponding registrations or storage writes; compiled-out features cannot be activated through runtime config.
- Preserve fail-closed protected-operation checks even when presentation integrations are omitted or public action hints are forged.
- Update workspace members/dependencies, facade exports/features, imports, examples, tests, Rustdoc and relevant specification/KB ownership records. Decide whether to remove the old crate immediately or provide a temporary re-export shim.
- Prove existing settings remain readable and behavior matches across web settings, flash, installed-app files and host policy, including malformed/duplicate cookies, corrupt files, mounted locations and failed saves.
- Build relevant native SSR and separate WASM hydrate/CSR graphs; run meaningful behavior tests, doctests and the repository's three review/refactoring rounds. Report coverage and actual platform limitations under the existing 70% development / 90% publication policy.
This issue records the accepted direction. Example APIs/feature names are suggestions until the design checkpoint; it does not request implementation, publication or deployment in this filing task.
Activity
cblanquera commentedon Oct 27, 2026
Suggested implementation plan
The consolidation is accepted; the module names, features and API signatures below are implementation proposals, not existing compile-verified interfaces.
1. Break the locale/view cycle first
A practical option is to keep the pure locale registry in
framework-language, and move the parts that understandBasePath,PublicLocation, route prefixes, cookies and view settings into view.Inventory
LocaleRegistrymethods andPreferenceActionbefore extraction: some currently combine locale and location behavior. Move those location-aware operations into a view adapter while retaining a single locale-validation authority. Do not add a reverse dependency just to preserve old method paths.A possible API boundary:
The final API must preserve the existing route/cookie/default precedence and encoded mount/query handling. Keeping a shared lower-level location-contract crate is another option if multiple independent consumers justify it, but avoid creating another crate solely to shuffle this cycle.
2. Move by responsibility, retaining behavior
Suggested destinations:
view::preferencesview::adapters::web, with shared data helpers exposed where neededview::flashview::accessview::adapters::native, optional and target-gatedKeep data/validation separate from host registration and file IO. Keep
framework-ui::stateand Leptos contexts in UI; they adapt public presentation values into reactive state.For access, keep both the display projection and actual admission API explicit:
The host still supplies identity/resource/Origin/CSRF decisions. A compile-time-disabled presentation feature must not select an unchecked implementation of protected work.
3. Separate pure features from host adapters
Illustrative additions to the view manifest, retaining its existing
serverfeature:This is a feature-boundary sketch, not a complete manifest. Resolve actual shared cookie/flash dependencies explicitly; target-gate existing native/server modules and retain the current Unix-only file implementation limitation.
Browser consumers can select pure preferences/flash data without server/native-file features. Native consumers may use file storage directly without registering web handlers. Test separate target/feature graphs: feature names do not themselves prove isolation, and Cargo features are additive.
4. Define plugin registration independently from module ownership
Possible application code after the registration contract is frozen:
Choose/document what the base view plugin actually registers; avoid an empty registration function for appearance. Expose web and native-specific registration separately if one entry point would hide transport policy.
Apply configuration before build and validate during startup. Do not automatically expose generic event dispatch. Reuse existing lifecycle/page registration; do not introduce a second dispatcher or start listeners from view startup.
5. Migrate imports without changing stored data
Update real consumers: ui-preferences shared/client/web, Profile UI client/native, root facade/features and any examples/docs found by a fresh search. Preserve
stackpress-locale,stackpress-theme,stackpress-flash,ui-preferences-v1.json, existing revisions and their serialization/persistence contracts.If a temporary compatibility crate is useful, make it depend only toward the new owner:
Account explicitly for old CookieScope/native_file paths and forward
native-fileif compatibility is promised. Never let view depend back on the shim. The language API migration is separate: wrappers there cannot depend on view if view now depends on language. Document deliberate Rust API changes instead of recreating a cycle.6. Verify in bounded stages
First prove the language extraction, then module migration, then optional registration and example wiring. Use behavior-focused before/after checks:
Run the required complexity, responsibility/abstraction and consistency/Rustdoc rounds with meaningful test verification. Update the architectural ownership documents after the API is settled. Report existing desktop/mobile proof limits rather than claiming new target support from this rearrangement.
cblanquera commentedon Oct 27, 2026
Coordination update: reusable Leptos ownership
See #17: the owner now requests extracting
framework-ui's reusable Leptos functionality intocrates/leptos, withframework-viewconsuming it through optional integration.The accepted consolidation in this issue remains: host preference selection/persistence, public flash policy and action-policy integration move into view. The Leptos contexts/components remain a distinct responsibility, now owned by the independent
stackpress-leptoslibrary.The earlier suggested diagram with
framework-ui → framework-viewis superseded by the intended edges below (arrows mean "depends on"):There are two cycles to avoid: this issue's existing language → view edge, and #17's existing UI → view edge. Resolve both in the shared ownership plan before reversing dependencies.
Use explicit adapters for public settings. For example, proposed post-migration imports:
The generic UI library must not import view's preference types or read cookies/native files. It receives initial values and callbacks; view/host code validates, persists and publishes acknowledged values. Preserve System mode, before-paint/hydration agreement, failed-save drafts, and authoritative host checks.
Update the migration map, facade/features, compatibility strategy and independent-consumer tests jointly with #17. Do not keep the old
framework-uidependency direction just to preserve examples; preserve behavior while making API/path migration explicit.Record G40: issue #15 removes the preferences crate outright; no-JS t…
Move preferences into framework-view and make the theme Light/Dark on…
Record issue #15 part 1 as verified and merged
Add framework-view preferences and flash plugin registrations (issue #15
Record issue #15 part 2 as verified and merged
Review rounds for issue #15 presentation code (part 3)
Record issue #15 part 3 as verified and update the theme re-check steps
Record owner acceptance of issue #15
Review rounds for issue #17 (part 3)