Changelog
All notable changes to Strata Storage will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[3.0.0] - 2026-09-01
localStorage and sessionStorage keys are written under strata:. Existing data migrates itself on
read, so most consumers do nothing — but set keyPrefix: false if anything outside this library reads a
physical key directly (a pre-paint theme script, a logger reading its own level). Migration keeps the
data reachable through this library; it cannot fix a hard-coded reader.
Breaking
localStorage/sessionStoragedefault to thestrata:key prefix (DEFAULT_WEB_KEY_PREFIX, exported). 2.9.0 made an unprefixed keyspace safe — a key is ours only if its value is aStorageValueenvelope — and this makes it tidy too, so our keys are identifiable by name.cookies(alreadystrata_),indexedDB,cache,memoryandurlare unchanged: none of them share a keyspace with other scripts.namespaceis unaffected and composes as<keyPrefix><namespace>:<key>.
Added
keyPrefix—false(or'') restores pre-3.0 behaviour; a string sets your own prefix. A per-adapteradapters.localStorage.prefixstill wins.migrateLegacyKeys(defaulttrue) — adopt pre-3.0 unprefixed entries on read.
Migration
A miss at strata:<key> falls back to the bare <key>; if the value is one of ours it is moved under the
prefix and returned. Three properties, each verified in a browser:
- Per key, on read — never a bulk sweep. A sweep would adopt every unprefixed envelope on the origin, including keys belonging to an instance that opted out or a sibling app still on 2.x.
- Never adopts a value that is not ours. A third-party key such as Microsoft Clarity's
_cltkis left exactly where it is. - Never overwrites. A value already at the prefixed key wins; the legacy entry is left alone.
Two applications sharing one origin with one still on 2.x: set migrateLegacyKeys: false on the upgraded
one, or better, give each a namespace — they were already colliding before this release.
Fixed
- A live timer no longer keeps a Node process alive. A short-lived script that created an instance and
never called
close()did not exit — measured hanging until killed at 120s, now exits immediately.
[2.9.0] - 2026-09-01
Closes the entire consumer-reported issue queue. No API changes and no data migration — every key stays exactly where it is.
Fixed
- Web adapters no longer treat other applications' keys as their own.
localStorage,sessionStorageand cookies are shared with every script on the origin, and the default key prefix is empty — so a name test matched every key there. An adapter now identifies its own data by shape: a key is its own only when the stored value is aStorageValueenvelope. This ends theFailed to get key … is not valid JSONerror stream (Microsoft Clarity's_cltkwas the usual trigger), keepskeys()to keys this library wrote, and closes two data-loss paths — the TTL sweep deleting a foreign key whose JSON carried an expiredexpires, and an unfilteredclear()wiping the origin. See Troubleshooting and Configuration ▸ key ownership. - An unscoped
subscribe()no longer throws. It fanned out across every registered adapter andindexedDBthrewNotSupportedError, commonly killing application boot. Non-observable backends are skipped. Seesubscribe(). - Per-adapter configuration reaches the adapter.
defineStorage({ adapters: { localStorage: { prefix: 'app:' } } })was a silent no-op on the synchronous path, which is usable beforeinitialize()resolves. Configuration is now applied synchronously at registration. defaultStoragesprotects the synchronous path too — withlocalStorageunavailable,setSyncnow falls through to the next listed backend instead of throwing.clear({ expiredOnly: true })was a guaranteed no-op onlocalStorage,sessionStorageand cookies, andcleanupExpired()reported0while doing the work. Both corrected.setLogLevel/getLogLevelare now exported. They were documented but unreachable — and they matter now, because skipped foreign keys are reported atdebug.- Documentation corrections. The
localStorageadapter page saidprefixdefaults to'strata_'; it defaults to''. The Capacitorpreferencespage documented aprefixoption that does not exist.
Changed
adapters: { <name>: false }now skips registration, not just initialization. Note thatdefaultStoragesis not a registration list — it picks the default adapter, while multi-adapter operations span everything registered.
Coming in 3.0.0
A real default key prefix for the web adapters, built on this release's shape check, with migrate-on-read and an opt-out for consumers whose physical key names are frozen.
[2.8.5] - 2026-07-25
README, packaging and metadata pass. The at-a-glance version row no longer ships stale, CHANGELOG.md
is included in the tarball, funding and a canonical repository.url were added, and homepage points
at this documentation site. dist/package.json was reduced to a two-field module marker so a publish
from dist/ cannot ship the wrong tree. No runtime code changes across 2.8.2–2.8.5.
2.8.2 was published from a stale tree: its bundled docs omitted the required npx cap sync native
setup step. It is deprecated on npm. Use 2.8.3 or later.
[2.8.1] - 2026-06-30
Documentation and metadata release — no runtime code changes, no API changes. Bug reports now
route to GitHub Issues; the AI Integration
Guide documents the npx cap sync native step, the registerCapacitorAdapters() helper, and the
TypeScript moduleResolution: "bundler" | "nodenext" requirement for subpath types. See the root
CHANGELOG.md for the full list.
[2.8.0] - 2026-06-27
License change: Apache-2.0 → MIT. A loosening of terms requiring no code changes on your part — the only condition is retaining the copyright and license notice. Versions at or before 2.7.1 remain available under Apache-2.0; 2.8.0 and later are MIT.
[2.7.0] - 2026-06-24
Audit-driven correctness and truthfulness release. No public API surface was
removed beyond dead config; the focus is making documented behavior match the
code. See the root CHANGELOG.md for the full itemized list.
Fixed
- Combined
compress+encryptpipeline now round-trips correctly. clear({ olderThan }), key/value validation, andclose()state reset behave as documented.import()/snapshot()round-trip metadata; auto-backup no longer self-nests.QueryOptions(limit/skip/sort/select) are honored andquery()decodes results; multi-adapter TTL cleanup and namespace key isolation work.- Encryption works in Node/SSR environments.
Changed
- Default storage order is now persistent-first.
- Compression is restricted to the
lzalgorithm —gzipwas never implemented and the option type is nowalgorithm?: 'lz'.
Removed
- Dead
strategyconfig and the unusedStorageStrategytype (type cleanup).
[2.6.1] - 2026-05-29
Changed
- Documentation patch release: README and AI integration guide were refreshed to cover the 2.6.0 native parity features.
- Development dependency patch updates only; no runtime/API behavior changed from 2.6.0.
[2.6.0] - 2026-05-27
Added
- SQLite multi-store — the
databaseandtableoptions are now honored on iOS and Android, so multiple independent SQLite stores (distinct database files and/or tables) no longer collapse into a single physical table. Use separatedefineStorageinstances (or distinctdatabase/tableconfig) to keep stores isolated. - Native filesystem backend —
FilesystemAdapternow works on iOS and Android (it was previously unavailable on every platform). One file per key under the app's documents/files directory (strata_storage/), storing the full value wrapper as JSON, with atomic writes;isAvailable()now returnstrue. size(true)— native SQLite and filesystem backends now return the{ keys, values, metadata }byte breakdown (the flag was previously ignored, returning only{ total, count }).
Fixed
- SQLite value round-trip — native
getnow returns the fullStorageValuewrapper ({ value, created, updated, expires, tags, metadata }) instead of a raw blob, so TTL, tags, and metadata survive a write→read cycle on iOS and Android. Corrupt/legacy rows are treated as a miss instead of throwing. - Filesystem key/temp-file collision — in-flight temp files now live in a
reserved staging subdirectory, so a key whose name resembles a temp file (e.g.
"backup.tmp") is never skipped bykeys()/size()or wrongly deleted byclear(). size().totalconsistency — native backends now include key bytes intotal, matching the web adapters' convention.- iOS SQLite bind safety — text/blob binds use
SQLITE_TRANSIENT, removing a latent use-after-free for transient Swift buffers.
Changed
androidx.security:security-cryptoupgraded1.1.0-alpha06→1.1.0(stable). TheEncryptedSharedPreferences/MasterKeyAPI is unchanged.- The native SQLite database file now resolves from the
databaseoption (defaultstrata_storage→strata_storage.db); table identifiers are sanitized to[A-Za-z0-9_]. Stored values remain bound parameters. - Marketing website tooling migrated to Yarn 4 (Corepack).
Notes
- The native iOS/Android changes in this release are code-complete and reviewed
but require on-device verification — follow
docs/guides/platforms/device-verification.md. Web/browser functionality is validated by the quality gates (typecheck + build + lint); the project ships no automated test runner.
[2.5.0] - 2026-05-26
Added
- Framework-agnostic, provider-free usage —
defineStorage()returns a ready-to-use instance you can create once and use anywhere, with no Provider/DI required (Zustand-style).createStrataHooks(instance)(React),createStrataComposables(instance)(Vue), andprovideStrata(instance)(Angular) bind to a created instance; the Provider/Plugin/Service APIs remain optional. - Synchronous API —
getSync/setSync/removeSync/hasSync/keysSync/clearSyncfor sync-capable adapters (memory, localStorage, sessionStorage, cookies, url). Async-only backends (indexedDB, cache, native) throw a clear error; sync set with encrypt/compress also throws (those are async). - URL-state adapter (
URLAdapter) — persist state in the query string (default) or hash fragment, withpopstate/hashchangechange events. - Disaster recovery (all opt-in) — FNV-1a integrity checksums with
corruption detection, durable write-verify-readback, mirroring to backup
adapters with read-repair, and
snapshot()/restore()plus scheduledautoBackup. - Exported integrity helpers (
computeChecksum/verifyChecksum) and error classes (e.g.IntegrityError) forinstanceofuse.
Fixed
- The React/Vue/Angular entry points are now actually built and shipped —
strata-storage/react|vue|angularpreviously resolved to files that were never compiled intodist/, so every framework import failed. - Multi-adapter operations (
keys/clear/size/subscribewith no explicitstorage) now span all registered adapters instead of only the default. - Cross-tab sync now applies received changes to local memory/IndexedDB/cache adapters (previously broadcasts were sent but never applied).
- AES-CBC now uses a correct 16-byte IV.
- Security: prototype-pollution guards in deep-merge/import/restore, ReDoS-capped
regex, and
SameSite=Lax+ automaticSecurecookie defaults. - iOS native plugin now registers with Capacitor (it had no registration and was non-functional); added missing native methods on iOS and Android; Keychain accessibility hardened.
Changed
- All diagnostic output now routes through a level-gated internal logger
(default
warn); the library no longer writes to the consumer console by default. Toggle withnew Strata({ debug: { enabled: true } }). - Dependencies updated to latest stable (including TypeScript 6 and ESLint 10). The default instance initializes lazily, so importing the package performs no I/O. Current quality gates are typecheck, build, lint, and CI; the project no longer ships an automated test runner.
[2.4.1] - 2024-12-26
Added
- Framework integration exports for React, Vue, and Angular
- Comprehensive root README.md
- Complete reference documentation (changelog, troubleshooting, FAQ)
- Missing API feature documentation
- SVG assets policy in CLAUDE.md
Fixed
- Package.json exports now include framework integrations
- Node.js version requirement aligned with documentation (18.0.0+)
- Broken links in documentation
Changed
- Updated documentation structure for better navigation
- Improved installation instructions
[2.4.0] - 2024-12-20
Added
- Firebase adapter integration
- Enhanced TypeScript types
- Capacitor plugin structure
Changed
- Improved error handling across all adapters
- Optimized IndexedDB performance
Fixed
- Cross-tab sync issues in Safari
- TTL expiration edge cases
[2.3.0] - 2024-12-15
Added
- Advanced query engine with tag-based filtering
- Data migration utilities
- Compression threshold configuration
- Custom serialization support
Changed
- Improved encryption performance
- Better memory management for large datasets
Fixed
- Memory leak in subscription system
- Edge cases in TTL cleanup
[2.2.0] - 2024-12-10
Added
- Cross-tab synchronization feature
- BroadcastChannel support for modern browsers
- Storage event fallback for older browsers
Changed
- Enhanced subscription API
- Improved event handling
Fixed
- Race conditions in concurrent operations
- Storage quota detection in private browsing
[2.1.0] - 2024-12-05
Added
- Compression support using LZ-string algorithm
- Configurable compression threshold
- Automatic compression for large objects
Changed
- Optimized serialization/deserialization
- Improved type safety
Fixed
- Issues with null/undefined values
- Circular reference handling
[2.0.0] - 2024-12-01
Added
- Complete rewrite with zero dependencies
- Native mobile support via Capacitor
- Encryption using Web Crypto API
- TTL (Time-To-Live) support
- Multiple storage adapter system
Changed
- BREAKING: New API design for consistency
- BREAKING: Removed dependency on @capacitor/preferences
- BREAKING: Changed configuration structure
Removed
- All external runtime dependencies
Migration Guide
See MIGRATION.md for detailed migration instructions from v1.x to v2.x.
[1.5.0] - 2024-11-15
Added
- Cookie storage adapter
- Cache API adapter
- FileSystem adapter for Capacitor
Fixed
- IndexedDB transaction handling
- Safari private browsing detection
[1.4.0] - 2024-11-01
Added
- SQLite adapter for mobile platforms
- Secure storage using Keychain (iOS) and EncryptedSharedPreferences (Android)
- Batch operations support
Changed
- Improved error messages
- Better TypeScript types
[1.3.0] - 2024-10-15
Added
- React hooks integration
- Vue composables
- Angular services
Fixed
- Memory adapter data persistence issues
- Edge cases in localStorage fallback
[1.2.0] - 2024-10-01
Added
- IndexedDB adapter with Promise-based API
- Automatic fallback chain
- Storage availability detection
Changed
- Enhanced platform detection
- Improved error handling
[1.1.0] - 2024-09-15
Added
- SessionStorage adapter
- Memory storage adapter
- Configuration validation
Fixed
- localStorage quota exceeded handling
- Type serialization edge cases
[1.0.0] - 2024-09-01
Added
- Initial release
- Basic localStorage adapter
- TypeScript support
- Core Strata class
- Simple get/set/remove/clear operations
Version Numbering
- Major version (X.0.0): Breaking changes, API changes
- Minor version (0.X.0): New features, backward compatible
- Patch version (0.0.X): Bug fixes, backward compatible
Support Policy
- Current version (2.x): Full support, active development
- Previous major version (1.x): Security fixes only for 6 months after 2.0 release
- Older versions: No longer supported
Reporting Issues
Found a bug or have a feature request? Please contact us.