Files
rspade_system/app/RSpade/man/storage.txt
root 9ebcc359ae Fix code quality violations and enhance ROUTE-EXISTS-01 rule
Implement JQHTML function cache ID system and fix bundle compilation
Implement underscore prefix for system tables
Fix JS syntax linter to support decorators and grant exception to Task system
SPA: Update planning docs and wishlists with remaining features
SPA: Document Navigation API abandonment and future enhancements
Implement SPA browser integration with History API (Phase 1)
Convert contacts view page to SPA action
Convert clients pages to SPA actions and document conversion procedure
SPA: Merge GET parameters and update documentation
Implement SPA route URL generation in JavaScript and PHP
Implement SPA bootstrap controller architecture
Add SPA routing manual page (rsx:man spa)
Add SPA routing documentation to CLAUDE.md
Phase 4 Complete: Client-side SPA routing implementation
Update get_routes() consumers for unified route structure
Complete SPA Phase 3: PHP-side route type detection and is_spa flag
Restore unified routes structure and Manifest_Query class
Refactor route indexing and add SPA infrastructure
Phase 3 Complete: SPA route registration in manifest
Implement SPA Phase 2: Extract router code and test decorators
Rename Jqhtml_Component to Component and complete SPA foundation setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 17:48:15 +00:00

268 lines
9.5 KiB
Plaintext
Executable File

RSX_STORAGE(1) RSpade Manual RSX_STORAGE(1)
NAME
Rsx_Storage - Scoped browser storage helper with automatic fallback
SYNOPSIS
// Session storage (cleared on tab close)
Rsx_Storage.session_set(key, value)
Rsx_Storage.session_get(key)
Rsx_Storage.session_remove(key)
// Local storage (persists across sessions)
Rsx_Storage.local_set(key, value)
Rsx_Storage.local_get(key)
Rsx_Storage.local_remove(key)
DESCRIPTION
Rsx_Storage provides safe, scoped access to browser sessionStorage and
localStorage with automatic handling of unavailable storage, quota exceeded
errors, and scope invalidation.
Key features:
- Automatic scoping by session, user, site, and build version
- Graceful degradation when storage unavailable (returns null)
- Automatic quota management (clears and retries when full)
- Scope validation (clears stale data on scope change)
- Developer-friendly key format for easy inspection
SCOPING SYSTEM
All storage keys are automatically scoped to prevent data leakage between:
- Different sessions (window.rsxapp.session_hash - hashed, non-reversible)
- Different users (window.rsxapp.user.id)
- Different sites (window.rsxapp.site.id)
- Different builds (window.rsxapp.build_key)
The scope is calculated by combining these values into a suffix:
session_hash_user_id_site_id_build_key
This scope is stored in the special key `_rsx_scope_key`. On page load, if
this key doesn't exist or doesn't match the current scope, all RSpade keys
are cleared and the new scope is stored.
The session_hash is a server-generated HMAC hash of the session cookie using
the application's encryption key, making it non-reversible while maintaining
consistency per session.
Example scope suffix:
a1b2c3d4e5f6_42_1_v2.1.0
└─ session ──┘ │ │ └─ build
user │
site
KEY FORMAT
Keys are stored with an `rsx::` namespace prefix, followed by the developer
key, followed by the scope suffix:
rsx::developer_key::scope_suffix
Example:
rsx::flash_queue::abc123def456_42_1_v2.1.0
The `rsx::` prefix serves two purposes:
1. Identifies RSpade keys for safe selective clearing (scope changes, quota)
2. Prevents collisions with other JavaScript libraries
This format allows developers to easily identify keys in browser developer
tools while maintaining proper scoping and coexistence with third-party
libraries. When inspecting storage, you'll see the `rsx::` prefix, your
original key name, and the scope suffix.
STORAGE AVAILABILITY
Rsx_Storage automatically detects if sessionStorage or localStorage are
available. Storage may be unavailable due to:
- Private browsing mode (some browsers block storage)
- Browser security settings
- Storage quota set to 0
- Browser bugs or incompatibilities
When storage is unavailable:
- set() operations are silently ignored (no error)
- get() operations return null
- remove() operations are silently ignored
This allows the application to continue functioning even when storage is
unavailable, as long as the stored data is non-critical.
SIZE LIMIT
Individual values larger than 1 MB are automatically rejected and not stored.
When attempting to store data > 1 MB:
- Operation is silently skipped (no error thrown)
- Console warning logged with actual size
- get() will return null for that key
This prevents quota issues and ensures browser storage remains performant.
If you need to store large data, consider:
- Storing server-side in database
- Using IndexedDB for large client-side data
- Splitting data into smaller chunks
QUOTA EXCEEDED HANDLING
When a set() operation fails due to quota exceeded (storage full), Rsx_Storage
automatically:
1. Clears only RSpade keys (keys starting with `rsx::`)
2. Preserves other libraries' data
3. Restores the _rsx_scope_key
4. Retries the set() operation once
If the retry also fails, the error is logged and the operation is abandoned.
This ensures the application continues functioning even when storage is full,
and minimizes impact on other JavaScript libraries sharing the same storage.
Only RSpade's previously stored data will be lost.
SCOPE INVALIDATION
Storage is automatically validated before every write operation. When the scope
changes, only RSpade keys (starting with `rsx::`) are cleared, preserving other
libraries' data.
Scope changes occur when:
- User logs in/out (user ID changes)
- User switches sites (site ID changes)
- Application is updated (build key changes)
- Session changes (rsx cookie changes)
This prevents stale data from one context bleeding into another context.
Example: User A logs in, stores preferences, logs out. User B logs in on the
same browser. User B sees clean RSpade storage, not User A's data. Other
libraries' data (e.g., analytics cookies, third-party preferences) remains
intact.
VOLATILE STORAGE WARNING
Browser storage is VOLATILE and can be cleared at any time. Never store data
critical to application functionality.
Storage can be lost due to:
- User clearing browser data
- Private browsing mode restrictions
- Quota exceeded errors (automatic clear + retry)
- Scope changes (logout, build update, session change)
- Browser storage unavailable
- Storage corruption or browser bugs
ONLY store data that is:
- Cached for performance (can be re-fetched)
- UI convenience state (non-essential)
- Transient messages (flash alerts, notifications)
If data is REQUIRED for the application to function correctly, store it
server-side in the database or PHP session.
EXAMPLES
Cache API response data (sessionStorage)
// Store cached data
const users = await fetch_users();
Rsx_Storage.session_set('cached_users', users);
// Retrieve cached data
let users = Rsx_Storage.session_get('cached_users');
if (!users) {
users = await fetch_users();
Rsx_Storage.session_set('cached_users', users);
}
Persist UI preferences (localStorage)
// Save theme preference
Rsx_Storage.local_set('theme', 'dark');
// Load theme preference
const theme = Rsx_Storage.local_get('theme') || 'light';
apply_theme(theme);
Store flash alert queue (sessionStorage)
// Queue persists across page navigation
Rsx_Storage.session_set('flash_queue', messages);
// Restore queue on next page
const messages = Rsx_Storage.session_get('flash_queue') || [];
Complex data structures
// Automatically JSON serialized
Rsx_Storage.local_set('user_prefs', {
theme: 'dark',
sidebar_collapsed: true,
recent_items: [1, 2, 3]
});
// Automatically JSON parsed
const prefs = Rsx_Storage.local_get('user_prefs');
console.log(prefs.theme); // 'dark'
Handling unavailable storage
// Always check for null (storage unavailable or key not found)
const cached = Rsx_Storage.session_get('data');
if (cached) {
use_cached_data(cached);
} else {
fetch_fresh_data();
}
Removing stale data
// Clean up when no longer needed
Rsx_Storage.session_remove('temp_data');
SESSIONSTORAGE VS LOCALSTORAGE
sessionStorage:
- Cleared when tab/window closes
- Not shared across tabs/windows
- Use for: temporary data, current session state, flash messages
localStorage:
- Persists across browser sessions
- Shared across all tabs/windows of same origin
- Use for: user preferences, cached data, long-term UI state
Both are scoped identically by Rsx_Storage (cookie, user, site, build).
MIGRATION FROM NATIVE STORAGE
If you're currently using sessionStorage/localStorage directly:
Before:
sessionStorage.setItem('my_key', JSON.stringify(data));
const data = JSON.parse(sessionStorage.getItem('my_key'));
sessionStorage.removeItem('my_key');
After:
Rsx_Storage.session_set('my_key', data);
const data = Rsx_Storage.session_get('my_key');
Rsx_Storage.session_remove('my_key');
Benefits:
- No manual JSON.stringify/parse
- Automatic scoping (prevents data leakage)
- Graceful handling of unavailable storage
- Automatic quota management
- Scope validation
DEBUGGING
Inspect storage in browser developer tools:
1. Open Developer Tools (F12)
2. Navigate to Application tab (Chrome) or Storage tab (Firefox)
3. Expand Session Storage or Local Storage
4. Look for keys matching: rsx::your_key::scope_suffix
The _rsx_scope_key shows the current active scope.
All RSpade keys are prefixed with `rsx::` for easy identification.
Console logging:
- Scope changes: "[Rsx_Storage] Scope changed, clearing RSpade keys only"
- First use: "[Rsx_Storage] Initializing scope (first use)"
- Quota exceeded: "[Rsx_Storage] Quota exceeded, clearing RSpade keys"
- Keys cleared: "[Rsx_Storage] Cleared X RSpade keys"
- Errors: "[Rsx_Storage] Failed to..."
FILE LOCATION
/system/app/RSpade/Core/Js/Rsx_Storage.js
SEE ALSO
Flash Alert system (uses Rsx_Storage for queue persistence)
php artisan rsx:man flash_alert
RSPADE January 2025 RSX_STORAGE(1)