Session Storage Adapter
The SessionStorageAdapter
extends the abstract StorageAdapter
class, providing a concrete implementation for persisting data to browser's
sessionStorage
. Unlike LocalStorageAdapter
,
data stored with this adapter is cleared when the browser session ends.
It offers enhanced capabilities including encryption, expiration
management, metadata tracking, and optional cross-tab synchronization.
1. Getting Started
Initialize the adapter with the desired options:
import SessionStorageAdapter from "storagefy";
const adapter = new SessionStorageAdapter({
dbName: "my-app", // required - creates namespace for your keys
encrypt: true, // optional, default false
version: 1, // optional, default 1
expireCheckInterval: 2000, // optional, default 1000ms
description: "Session store", // optional
channelName: "session-channel" // optional - used for sync between tabs
enableSyncTabs: false, // optional, default false - Whether to enable sync automatically on change key value
});
The channelName
enables automatic synchronization of data across
open tabs using the CrossTabChannel
communication system. This
is particularly useful for session-based applications where you want to maintain
state consistency across multiple tabs within the same browser session.
2. Core Concepts
Session-Based Storage
Unlike localStorage, data in sessionStorage is cleared when the page session ends — that is, when the tab is closed or the browser is shut down. This makes it ideal for temporary data that should not persist beyond the current browser session.
Storage Namespacing
All keys are automatically namespaced using the format {dbName}__
to avoid conflicts with other applications using sessionStorage. When
encryption is enabled, keys are additionally obfuscated using a simple
algorithm.
Encryption
When the encrypt: true
option is set, all values are encrypted
before storage and decrypted when retrieved using the cryptoHelper
module. Keys are also obfuscated to enhance security.
Cross-Tab Communication
When a channelName
is provided, changes to data are broadcast
across browser tabs using the CrossTabChannel
mechanism. This
enables real-time synchronization of state across multiple open instances
of your application within the same session.
Expiration Management
The adapter includes a built-in expiration system that automatically
removes expired items at regular intervals (configurable via expireCheckInterval
). This helps manage temporary data without manual cleanup.
3. Test It
wait the animation to finish before go to another tab!
SessionStorage Content:
4. API Reference
await adapter.get(key)
Retrieves a value. Returns null
if not found or expired. Handles
decryption automatically if encryption is enabled.
await adapter.set("sessionId", "abc123");
const value = await adapter.get("sessionId"); // "abc123"
await adapter.set(key, value, expire?)
Stores a value. Optional expire
is in milliseconds from now.
Handles encryption automatically if enabled and broadcasts changes to other
tabs if using a channel.
// Save a form state that expires in 30 minutes
await adapter.set("formState", formData, 30 * 60 * 1000);
await adapter.delete(key)
Removes a key and its expiration metadata. Also broadcasts deletion to other tabs if using a channel.
await adapter.delete("sessionId");
await adapter.list(prefix?)
Returns all keys/values matching the prefix (defaults to all in namespace). Decrypts values if encryption is enabled.
await adapter.set("form.name", "John");
await adapter.set("form.email", "john@example.com");
const formData = await adapter.list("form.");
// [{ key: "form.name", value: "John" }, { key: "form.email", value: "john@example.com" }]
await adapter.has(key)
Returns true
if the key exists in the session storage.
await adapter.has("sessionId"); // true or false
await adapter.clear()
Clears all data, including metadata and expirations, within this adapter's namespace.
await adapter.clear();
await adapter.reset()
Removes only data keys related to the namespace, not metadata. Useful for clearing user data while preserving system configuration.
await adapter.reset();
await adapter.setExpire(key, timestamp)
Set a custom expiration time (timestamp in ms) for a specific key.
const future = Date.now() + 10000;
await adapter.setExpire("sessionId", future);
await adapter.getExpire(key)
Returns the expiration timestamp for a key, or null
if no
expiration is set.
const expireTime = await adapter.getExpire("sessionId");
// Returns timestamp or null
await adapter.deleteExpire(key)
Removes the expiration for the given key, making it persist until the session ends.
await adapter.deleteExpire("sessionId");
await adapter.clearExpire()
Deletes all keys that have expired based on their timestamps.
await adapter.clearExpire();
adapter.destroy()
Cleans up resources, stops the expiration timer, and removes event listeners. Called automatically on page unload.
adapter.destroy(); // Clean up before component unmount
adapter.emitDataChange(key, value, origin)
Explicitly broadcasts a data change event to other tabs (usually called automatically by set/delete).
adapter.emitDataChange("wizard-state", newState, "tab-123");
adapter.onDataChanged(callback)
Registers a callback function to handle data changes from other tabs or contexts.
adapter.onDataChanged(({ key, value, origin }) => {
console.log(`Session data for ${key} changed in tab ${origin}`);
// Update UI or app state accordingly
});
5. Advanced Usage
Multi-Step Form Data Management
The adapter is ideal for managing state in multi-step forms where you want to preserve progress within a session:
// Save form state after each step
function saveFormStep(stepNumber, formData) {
adapter.set(`form-step-${stepNumber}`, formData);
}
// Recover a specific step's data
async function loadFormStep(stepNumber) {
return await adapter.get(`form-step-${stepNumber}`);
}
// Check if a step has been completed
async function isStepCompleted(stepNumber) {
return await adapter.has(`form-step-${stepNumber}`);
}
Session Management
Managing user sessions with automatic expiration:
// Store session info with expiration
const sessionDuration = 20 * 60 * 1000; // 20 minutes
await adapter.set("session-token", token, sessionDuration);
// Extend session on activity
function extendSession() {
adapter.setExpire("session-token", Date.now() + sessionDuration);
}
// Check if session is valid
async function isSessionActive() {
return await adapter.has("session-token");
}
Multi-Tab Wizard Synchronization
Keep multi-step wizards in sync across tabs:
// In your wizard component
const wizardAdapter = new SessionStorageAdapter({
dbName: "wizard",
channelName: "wizard-sync"
});
// Update current step
function goToStep(stepNumber) {
wizardAdapter.set("current-step", stepNumber);
}
// Listen for changes from other tabs
wizardAdapter.onDataChanged(({ key, value }) => {
if (key === "current-step") {
// Update the UI to show the new step
renderWizardStep(value);
}
});
6. Comparison with LocalStorageAdapter
Feature | SessionStorageAdapter | LocalStorageAdapter |
---|---|---|
Persistence | Until tab/browser closes | Indefinite (until manually cleared) |
Data Visibility | Only within the same tab by default | Available across all tabs/windows |
Best Use Cases | Form state, wizards, temporary authentication | User preferences, long-term settings, cached data |
Storage Limit | ~5MB per origin | ~5MB per origin |
Cross-Tab Sync | Requires explicit channelName | Requires explicit channelName |
7. Notes
- Data is automatically cleared when the browser session ends (tab closed, browser shut down).
-
Keys are namespaced under
{dbName}__
to avoid conflicts. -
A
beforeunload
event listener is registered to properly clean up resources. - Expirations are automatically checked and removed in intervals (default 1s).
-
Encryption only applies if enabled via
encrypt: true
option. - The adapter handles browser storage limits gracefully with error logging.
-
Use
channelName
if you need to synchronize session data across multiple tabs.