Skip to content

Storage Management

The Store Module provides a unified encapsulation of the entire browser storage chain. From page-level temporary memory to persistent LocalStorage/Cookies and high-volume IndexedDB, you can manage everything through a consistent API style.

Import Method

javascript
import { tStore, tDBM } from "@techui/utils";

Temporary Memory Storage

tStore itself is a lightweight global state cache pool. It is implemented based on Map, meaning data is only valid during the current page lifecycle and is lost upon refresh. It is more lightweight than Vuex/Pinia and is ideal for sharing data in non-Vue component environments, such as pure JS utility functions.

Core API

  • s(key, val): Set. Writes data.
  • g(key, del?): Get. Reads data. If del is true, the data is deleted immediately after reading ("burn after reading").
  • d(key): Delete. Deletes data.

Scenario 1: Cross-component/Module Parameter Passing

Share configurations between two independent JS modules without introducing complex state management libraries.

javascript
// moduleA.js
tStore.s('appConfig', { 
  apiHost: 'https://api.techui.net',
  timeout: 5000 
});

// moduleB.js
const config = tStore.g('appConfig');
console.log(config.apiHost); // "https://api.techui.net"

Scenario 2: Flash Message

Commonly used for success prompts after page redirection. The data is automatically destroyed after one read to prevent duplicate displays.

javascript
// On the login page
tStore.s('loginSuccessMsg', 'Welcome back, Ayin!');

// During home page initialization
const msg = tStore.g('loginSuccessMsg', true); // true enables burn-after-reading
if (msg) {
  alert(msg); // Displays welcome message
}

// Read again
console.log(tStore.g('loginSuccessMsg')); // undefined

tStore.cookie provides a simple wrapper for document.cookie, resolving the clunky nature of native Cookie operations.

Core API

  • s(name, val, expire): Write. expire is the expiration time in seconds.
  • g(name): Read. Automatically performs unescape decoding.
  • d(name): Delete.

Scenario 1: Set Short-term Token (1 Hour)

javascript
// Login successful, save Token valid for 3600 seconds
tStore.cookie.s('access_token', 'eyJhbGciOiJIUz...', 3600);

Scenario 2: Set Long-term Preference (7 Days)

javascript
// Save user ad preferences, valid for 7 days
const sevenDays = 60 * 60 * 24 * 7;
tStore.cookie.s('ad_preference', 'low', sevenDays);
javascript
// Clear upon logout
tStore.cookie.d('access_token');

// Verify deletion
console.log(tStore.cookie.g('access_token')); // "" (empty string)

Local Storage

tStore.local is an enhanced wrapper for localStorage. Its most significant feature is automatic serialization, eliminating the need to manually write JSON.stringify and JSON.parse.

Core API

  • s(key, val): Write. Supports any type, including objects, arrays, and strings.
  • g(key): Read. Includes built-in JSON parsing fault tolerance.
  • d(key): Delete.

Scenario 1: Persistent User Settings

Configurations that remain even after the user closes the browser.

javascript
// Write an object
const settings = {
  theme: 'dark',
  fontSize: 14,
  sidebarCollapsed: true
};
tStore.local.s('user_settings', settings);

Scenario 2: Reading and Using Data

javascript
const savedSettings = tStore.local.g('user_settings');

if (savedSettings && savedSettings.theme === 'dark') {
  enableDarkMode();
}

Scenario 3: Fault Tolerance

If a key is incorrectly written as a non-JSON string by an external script (e.g., "undefined"), tStore will gracefully fall back and return the original string rather than throwing an error that could crash the page.

javascript
// Simulate dirty data
localStorage.setItem('bad_data', '{ key: "invalid json" }'); // Invalid JSON missing quotes

const val = tStore.local.g('bad_data');
console.log(val); // Returns the string as-is without throwing SyntaxError

Session Storage

The API for tStore.session is identical to local, but the data is only valid until the current tab is closed.

Scenario 1: Temporary Form Drafts

If a user refreshes the page while filling out a long form, data should not be lost; however, it should be cleared after closing the tab to avoid polluting future operations.

javascript
// Monitor input changes
input.addEventListener('input', (e) => {
  tStore.session.s('form_draft_title', e.target.value);
});

// Restore on page load
const draft = tStore.session.g('form_draft_title');
if (draft) input.value = draft;

Scenario 2: Page Visit Breadcrumbs

Record the user's access path within the current session.

javascript
const history = tStore.session.g('breadcrumbs') || [];
history.push({ name: 'UserDetail', id: 101 });
tStore.session.s('breadcrumbs', history);

Browser Database

tDBM (TechUI Database Manager) is the most powerful tool in this module. It encapsulates complex IndexedDB operations into simple Promise calls, making it suitable for storing large amounts of structured data such as logs, offline documents, or large-screen data caches.

Initialize Structure (Init)

Before use, you must define the database table structure (Schema).

javascript
// Define table structure
const stores = [
  {
    name: 'logs',         // Table name
    keyPath: 'id',        // Primary key
    autoIncrement: true,  // Auto-increment
    indexes: [            // Indexes
      { name: 'level', keyPath: 'lvl' },
      { name: 'date', keyPath: 'timestamp' }
    ]
  },
  {
    name: 'cache_files',
    keyPath: 'url'        // Use URL as primary key
  }
];

// Initialize database 'MyAppDB' with version 1
await tDBM.init('MyAppDB', 1, stores);

Scenario 1: Batch Writing (High Performance)

Much faster than calling add in a loop; ideal for initial data imports.

javascript
const logs = [
  { lvl: 'info', msg: 'App started', timestamp: Date.now() },
  { lvl: 'error', msg: 'Network error', timestamp: Date.now() + 100 },
];

// Batch insert
await tDBM.add('logs', logs);
console.log('Log writing complete');

Scenario 2: Update or Insert (Upsert)

Used for synchronizing server data: updates if the ID exists, inserts if it doesn't.

javascript
const userProfile = {
  url: '/api/user/1',
  data: { name: 'Ayin', role: 'admin' },
  cachedAt: Date.now()
};

// Use put method
await tDBM.put('cache_files', userProfile);

Scenario 3: Query by Index

Query data using business fields rather than just the ID.

javascript
// Query all 'error' level logs
const errors = await tDBM.getByIndex('logs', 'level', 'error');
console.log(`Found ${errors.length} error logs`);

Scenario 4: Cursor Traversal for Large Datasets

When a table contains tens of thousands of records, using getAll directly may cause memory overflow. Use the iterate cursor to process items one by one.

javascript
// Traverse all logs
await tDBM.iterate('logs', (cursor, value) => {
  if (value.timestamp < Date.now() - 86400000) {
    // Delete expired logs older than 1 day
    cursor.delete(); 
    console.log('Deleted expired log:', value.id);
  }
});

Scenario 5: Database Information and Maintenance

javascript
// Check if database is initialized
if (tDBM.isInited()) {
  const info = tDBM.info();
  console.log(`Version: ${info.version}, Tables: ${info.tables.join(',')}`);
}

// Completely delete database (connection must be closed first)
tDBM.close();
await tDBM.deleteDatabase('MyAppDB');

Released under the MIT License.