$ show nbubna/store
This repository is a lightweight JavaScript library that provides a feature-rich wrapper around the browser's `localStorage` and `sessionStorage` APIs. It offers a unified API for storing, retrieving, and manipulating JSON data, with support for namespacing, multiple storage areas (local, session, page, custom), and a plugin system for extensions. The core module (`src/store2.js`) implements a Store constructor that creates namespace-aware stores, with methods like `get`, `set`, `remove`, `clear`, `each`, `keys`, `transact`, and `add`. It also includes a fake storage fallback for environments where Web Storage is unavailable. The architecture is modular: the core is augmented by optional extension files (e.g., caching, array operations, event handling, cookie backing) that hook into internal methods via `store._`. The library is production-ready, with extensive unit tests and CI via Travis CI (though using Node.js 9, which is outdated). Key entry points are the `store` function and its namespace/area methods, which expose the entire API.
The LLM identified 5 files worth highlighting for reuse:
Extends the store API with all Array.prototype methods (push, pop, indexOf, etc.) on stored values. It safely wraps array operations, handling non-array values by converting them into single-element arrays, and removes the key if the resulting array is empty. This demonstrates a reusable pattern for extending a storage interface with arbitrary data manipulation functions.
Enables retrieving and setting values deep inside stored objects using dot-separated keys (e.g., `store.get('user.address.city')`). It overrides the core `get` method to split the key and recursively resolve the path within the parsed object. Implements a safe `resolvePath` helper that avoids `eval` (fixing a previous security issue). This component is self-contained and can be reused in any project needing nested key access.
Handles `QUOTA_EXCEEDED_ERR` by transparently shifting excess data to a temporary in-memory fake storage area, so writes never throw. It also overrides `get`, `remove`, `key`, `length`, and `clear` to aggregate both the real and overflow areas. This pattern is reusable for any storage layer that needs graceful degradation under quota limits.
Adds time-based expiration to stored values. When `set` is called with a numeric third argument (seconds), it prefixes the stored string with an expiration timestamp. The `get` method checks the timestamp and automatically removes expired entries. Uses a simple prefix/suffix format (`exp@<timestamp>;`) that can be parsed without breaking existing data. This is a clean, reusable implementation of TTL for any storage system.
Provides `on`, `off`, and `once` methods for listening to storage events scoped to particular keys, namespaces, or storage areas. It wraps the native `window.storage` event and enriches it with parsed values, namespace info, and optional expiration metadata (when combined with `store.cache`). The implementation gracefully degrades when `window.addEventListener` is unavailable. This component is a generic event abstraction that could be applied to other storage-like APIs.