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

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.