strata-storage 2.8.2 → 2.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-INTEGRATION-GUIDE.md +21 -5
- package/CHANGELOG.md +457 -0
- package/README.md +436 -413
- package/dist/package.json +2 -107
- package/package.json +18 -18
- package/scripts/build.js +18 -56
- package/scripts/postinstall.js +14 -11
- package/dist/README.md +0 -543
package/AI-INTEGRATION-GUIDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AI Integration Guide - strata-storage
|
|
2
2
|
|
|
3
|
-
Quick reference for AI development agents (Claude Code, Cursor, Copilot, etc.) to integrate `strata-storage` into web and mobile projects. Current version: **2.8.
|
|
3
|
+
Quick reference for AI development agents (Claude Code, Cursor, Copilot, etc.) to integrate `strata-storage` into web and mobile projects. Current version: **2.8.3**.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -209,9 +209,16 @@ const storage = defineStorage();
|
|
|
209
209
|
|
|
210
210
|
### Capacitor (native)
|
|
211
211
|
|
|
212
|
+
`strata-storage` ships as a Capacitor plugin (native iOS + Android). In a Capacitor
|
|
213
|
+
app, after installing run **`npx cap sync`** so the native module is copied into the
|
|
214
|
+
iOS/Android projects — the native adapters (`secure`, `sqlite`, `preferences`,
|
|
215
|
+
`filesystem`) **do not work on-device without it**. No manual plugin registration in
|
|
216
|
+
JS is needed; Capacitor auto-discovers the `StrataStorage` plugin.
|
|
217
|
+
|
|
212
218
|
```typescript
|
|
213
219
|
import { defineStorage } from 'strata-storage';
|
|
214
220
|
import {
|
|
221
|
+
registerCapacitorAdapters,
|
|
215
222
|
PreferencesAdapter,
|
|
216
223
|
SecureAdapter,
|
|
217
224
|
SqliteAdapter,
|
|
@@ -219,10 +226,15 @@ import {
|
|
|
219
226
|
} from 'strata-storage/capacitor';
|
|
220
227
|
|
|
221
228
|
const storage = defineStorage();
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
229
|
+
|
|
230
|
+
// Easiest — register all four native adapters at once (also refreshes the active set):
|
|
231
|
+
await registerCapacitorAdapters(storage);
|
|
232
|
+
|
|
233
|
+
// …or register individually for fine-grained control / custom adapter config:
|
|
234
|
+
// storage.registerAdapter(new SecureAdapter());
|
|
235
|
+
// storage.registerAdapter(new SqliteAdapter()); // 2.6.0 — multi-store (database + table)
|
|
236
|
+
// storage.registerAdapter(new FilesystemAdapter()); // 2.6.0 — file-per-key, atomic writes
|
|
237
|
+
|
|
226
238
|
await storage.set('secret', token, { storage: 'secure' });
|
|
227
239
|
```
|
|
228
240
|
|
|
@@ -315,6 +327,8 @@ const storage = defineStorage({
|
|
|
315
327
|
| Issue | Solution |
|
|
316
328
|
|-------|----------|
|
|
317
329
|
| Framework import fails | Ensure `strata-storage >= 2.5.0` (earlier versions never shipped the built entry points). |
|
|
330
|
+
| TS can't find types for `strata-storage/react` \| `/vue` \| `/angular` \| `/capacitor` \| `/firebase` | Set `"moduleResolution": "bundler"` (or `"nodenext"`) in `tsconfig.json`. The package is ESM-only and exposes typed `exports` subpaths; classic `"node"` resolution can't see them. Modern Vite / Angular / Vue templates already use `bundler`/`nodenext`. |
|
|
331
|
+
| Native adapters do nothing on device | Run `npx cap sync` after install so the native iOS/Android module is wired in, then register the Capacitor adapters (`registerCapacitorAdapters(storage)`). |
|
|
318
332
|
| "does not support synchronous operations" | The targeted adapter is async-only; use the async API or a sync-capable adapter. |
|
|
319
333
|
| Sync set throws on encrypt/compress | Encryption/compression are async — use `await storage.set(...)`. |
|
|
320
334
|
| `useStrata must be used within <StrataProvider>` | Use `createStrataHooks(instance)` for provider-free code. |
|
|
@@ -334,6 +348,8 @@ Full documentation lives at **https://stratastorage-docs.aoneahsan.com**:
|
|
|
334
348
|
- [Changelog](https://stratastorage-docs.aoneahsan.com/reference/changelog)
|
|
335
349
|
- Machine-readable: [`/llms.txt`](https://stratastorage-docs.aoneahsan.com/llms.txt) · [`/llms-full.txt`](https://stratastorage-docs.aoneahsan.com/llms-full.txt)
|
|
336
350
|
|
|
351
|
+
Project: [npm](https://www.npmjs.com/package/strata-storage) · [GitHub](https://github.com/aoneahsan/strata-storage) · [Report an issue](https://github.com/aoneahsan/strata-storage/issues)
|
|
352
|
+
|
|
337
353
|
---
|
|
338
354
|
|
|
339
355
|
Developed with ❤️ by the **Strata Storage Team** — maintained by [Ahsan Mahmood](https://aoneahsan.com). Questions or integration help: **aoneahsan@gmail.com**.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Strata Storage will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.8.4] - 2026-07-25
|
|
9
|
+
|
|
10
|
+
Documentation, metadata and packaging pass — **no runtime code changes**, no API changes. Brings the
|
|
11
|
+
package to the house documentation standard and closes three packaging defects.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **`dist/package.json` no longer declares `name: "strata-storage"`.** The build wrote a complete second
|
|
16
|
+
manifest into `dist/`, carrying the package name and version. Two manifests sharing one name means
|
|
17
|
+
`cd dist && npm publish` succeeds and ships the wrong tree under the real package name — the structural
|
|
18
|
+
cause of the 2.8.2 incident. `dist/package.json` is now a two-field module marker
|
|
19
|
+
(`{ "type": "module", "sideEffects": false }`), so that publish fails immediately for want of a name.
|
|
20
|
+
Resolution is unaffected: it is governed entirely by the root manifest's `exports` map.
|
|
21
|
+
- **`funding` added** to `package.json`, so npm and `npm fund` surface the support link.
|
|
22
|
+
- **`CHANGELOG.md` now ships in the tarball.** It was absent from the `files` allowlist and npm does not
|
|
23
|
+
add it automatically, so installed copies had no version history. `README.md` and `LICENSE` are now
|
|
24
|
+
listed explicitly too.
|
|
25
|
+
- **`homepage` points at the documentation site** (`stratastorage-docs.aoneahsan.com`) rather than the
|
|
26
|
+
marketing site, so npmjs.com's primary link lands on the docs. The marketing site remains linked from
|
|
27
|
+
the README.
|
|
28
|
+
- **`repository.url` uses the `git+https://` form** npm expects for a git remote.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- **README rewritten to the canonical package pattern** — anchored, linkable sections; a table of
|
|
33
|
+
contents; absolute links throughout (npm renders the README outside the repo, where relative links are
|
|
34
|
+
dead); and new **Limitations** and **Troubleshooting** sections that state plainly what the package does
|
|
35
|
+
not do: ESM-only, no automated test suite, non-cryptographic integrity checksums, minimal Node support,
|
|
36
|
+
and the open `ISSUE-01` empty-prefix defect with its `prefix` mitigation.
|
|
37
|
+
- **`description` shortened** to `One storage API across web, iOS and Android — zero runtime
|
|
38
|
+
dependencies.`, matching the README's one-line promise.
|
|
39
|
+
- **`keywords` trimmed from 16 to 12** and normalised to lower case.
|
|
40
|
+
- **`.npmignore` deleted.** `files` is an allowlist and already governed the tarball completely — verified
|
|
41
|
+
by comparing `npm pack --dry-run` file lists with and without the file, which were identical. Keeping a
|
|
42
|
+
denylist alongside it only risks disagreement.
|
|
43
|
+
- **`dist/README.md` is no longer generated**, removing a duplicate copy of the largest text file in the
|
|
44
|
+
tarball.
|
|
45
|
+
- Added `assets/logo.svg` as the brand master, and `docs/PACKAGES.md` as the dependency inventory.
|
|
46
|
+
|
|
47
|
+
## [2.8.3] - 2026-07-25
|
|
48
|
+
|
|
49
|
+
Documentation and metadata release — **no runtime code changes**, no API changes. Restores the
|
|
50
|
+
documentation that 2.8.2 reverted, and repoints the docs links at the standalone documentation site.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- **Restored the native-setup documentation that 2.8.2 dropped.** The README and the AI Integration
|
|
55
|
+
Guide again document the required `npx cap sync` step and the `registerCapacitorAdapters(storage)`
|
|
56
|
+
helper. Without `cap sync` the native adapters (`secure`, `sqlite`, `preferences`, `filesystem`) do
|
|
57
|
+
not work on-device, so 2.8.2 shipped a materially misleading omission for Capacitor apps.
|
|
58
|
+
- **`bugs.url` routes to GitHub Issues again** (`https://github.com/aoneahsan/strata-storage/issues`),
|
|
59
|
+
as in 2.8.1. The marketing-site contact form remains a secondary channel.
|
|
60
|
+
- Corrected stale version strings — the README still advertised `2.8.0`.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **The documentation site now lives in its own repository:**
|
|
65
|
+
[aoneahsan/strata-storage-docs](https://github.com/aoneahsan/strata-storage-docs) →
|
|
66
|
+
<https://stratastorage-docs.aoneahsan.com>. README links now point at the hosted site instead of
|
|
67
|
+
in-repo `./docs` paths, and this repository's `docs/` holds internal records only.
|
|
68
|
+
|
|
69
|
+
## [2.8.2] - 2026-06-30
|
|
70
|
+
|
|
71
|
+
⚠️ **Published in error — superseded by 2.8.3. Prefer 2.8.1 or 2.8.3.**
|
|
72
|
+
**Deprecated on npm 2026-07-25**, so installing it now prints a warning pointing at 2.8.3.
|
|
73
|
+
|
|
74
|
+
Released ~55 minutes after 2.8.1 from a stale working tree. The compiled output is byte-identical to
|
|
75
|
+
2.8.1 (no runtime code changed, no API changed), but the **bundled documentation reverted to a
|
|
76
|
+
pre-2.8.1 state**: the `npx cap sync` native-setup step and the `registerCapacitorAdapters()` helper
|
|
77
|
+
were removed from both the README and the AI Integration Guide, and `bugs.url` was pointed at the
|
|
78
|
+
marketing-site contact form. The version bump was never committed or tagged here, which is why this
|
|
79
|
+
file carried no entry for it until 2.8.3 reconstructed one by diffing the published tarballs.
|
|
80
|
+
|
|
81
|
+
## [2.8.1] - 2026-06-30
|
|
82
|
+
|
|
83
|
+
Documentation and metadata release — **no runtime code changes**, no API changes. Safe drop-in
|
|
84
|
+
upgrade from 2.8.0.
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
|
|
88
|
+
- **Bug reports now route to GitHub Issues.** `package.json` `bugs.url` →
|
|
89
|
+
`https://github.com/aoneahsan/strata-storage/issues`, and the README "Support" section leads with
|
|
90
|
+
opening a GitHub issue (the marketing-site contact form remains a secondary channel).
|
|
91
|
+
- **AI Integration Guide refreshed to 2.8.1** and made more complete for AI coding agents:
|
|
92
|
+
the Capacitor section now documents the required `npx cap sync` native-setup step and the
|
|
93
|
+
`registerCapacitorAdapters(storage)` helper, and a troubleshooting entry covers the TypeScript
|
|
94
|
+
`moduleResolution: "bundler" | "nodenext"` requirement for the typed subpath exports
|
|
95
|
+
(`strata-storage/react` · `/vue` · `/angular` · `/capacitor` · `/firebase`).
|
|
96
|
+
- **README** gained a `npx cap sync` note in the iOS/Android section, an explicit GitHub repo link,
|
|
97
|
+
and a cleaned-up Links/Support section (removed a stray internal auto-generated links block).
|
|
98
|
+
|
|
99
|
+
## [2.8.0] - 2026-06-27
|
|
100
|
+
|
|
101
|
+
Licensing change — **Strata Storage is now released under the MIT License** (relicensed from
|
|
102
|
+
Apache-2.0). MIT is the most widely adopted permissive open-source license, with no patent or
|
|
103
|
+
attribution-in-docs clauses; the only condition is retaining the copyright and license notice. This
|
|
104
|
+
is a *loosening* of terms and requires no code changes on your part.
|
|
105
|
+
|
|
106
|
+
### Changed
|
|
107
|
+
|
|
108
|
+
- **License: Apache-2.0 → MIT.** The `LICENSE` file now contains the standard MIT text, and the
|
|
109
|
+
`license` field in `package.json` is `"MIT"`. The previous non-standard "Additional Terms" appended
|
|
110
|
+
to the Apache license have been removed; the "Strata Storage" name remains a trademark of the
|
|
111
|
+
maintainer (covered by trademark law, not the code license). Versions published at or before 2.7.1
|
|
112
|
+
remain available under Apache-2.0 — only 2.8.0 and later are MIT.
|
|
113
|
+
- **Repository secret posture for public release.** `.gitignore` now ignores real `.env` files and
|
|
114
|
+
tracks only `*.env.example` templates (the repo previously tracked real env files as a private
|
|
115
|
+
repo). A pre-publication audit of the working tree and full git history confirmed no real secrets
|
|
116
|
+
are present.
|
|
117
|
+
|
|
118
|
+
## [2.7.1] - 2026-06-25
|
|
119
|
+
|
|
120
|
+
Correctness release: an internal audit found several defects in 2.7.0 —
|
|
121
|
+
including a broken TypeScript types entry, a silent compression data-loss bug,
|
|
122
|
+
and a TTL-expiry crash — all fixed here. No manual migration is required
|
|
123
|
+
(legacy compressed values still decode).
|
|
124
|
+
|
|
125
|
+
### Fixed
|
|
126
|
+
|
|
127
|
+
- **Published types were unusable** — `dist/index.d.ts` re-exported from a
|
|
128
|
+
non-existent `./types.js`, so `import type { … } from 'strata-storage'` failed
|
|
129
|
+
to compile for every TypeScript consumer under `nodenext`/`bundler`. The build
|
|
130
|
+
now resolves directory-barrel imports to `/index.js`.
|
|
131
|
+
- **Compression silently corrupted non-Latin1 data** — the bundled LZ codec
|
|
132
|
+
misread any character ≥ U+0100 (CJK, emoji, many symbols) above the
|
|
133
|
+
compression threshold, returning garbage or throwing on read. The codec now
|
|
134
|
+
operates over UTF-8 bytes with fixed-width tokens. Values compressed by ≤ 2.7.0
|
|
135
|
+
still decode via a legacy read path, so **no data migration is needed**.
|
|
136
|
+
- **TTL expiry could crash** — reading an expired entry on
|
|
137
|
+
localStorage/sessionStorage/cookie recursed `getSync → removeSync` into a stack
|
|
138
|
+
overflow (Cache hung asynchronously). This fired on its own via the periodic
|
|
139
|
+
TTL cleanup. Removal now reads the raw stored value without re-triggering the
|
|
140
|
+
expiry path, and only when a change listener needs the old value.
|
|
141
|
+
- **Firebase** — Firestore/Realtime writes threw on `undefined` wrapper fields
|
|
142
|
+
(`expires`/`tags`/`metadata` on a plain write); those are now stripped before
|
|
143
|
+
writing. `enableFirebaseSync()` now attaches the adapters to the active set, so
|
|
144
|
+
a top-level `subscribe()`/`keys()`/`clear()`/`size()` includes them
|
|
145
|
+
immediately.
|
|
146
|
+
- **Namespace isolation** — keys containing `:` could collide across namespaces
|
|
147
|
+
(`ns 'a' + key 'b:c'` vs `ns 'a:b' + key 'c'`); namespace prefixes are now
|
|
148
|
+
encoded so they can never alias.
|
|
149
|
+
- **Default storage** — a bare `new Strata({})` / `defineStorage()` with no
|
|
150
|
+
config defaulted to memory-only; it now prefers persistent backends first
|
|
151
|
+
(`localStorage → indexedDB → sessionStorage → memory`), matching the default
|
|
152
|
+
`storage` singleton and the documented behavior.
|
|
153
|
+
- **Conflict resolution** — the default `'latest'` cross-tab strategy now keeps
|
|
154
|
+
the most-recent write by timestamp (tabs converge) instead of last-received.
|
|
155
|
+
- **Cross-tab `clear()`** now propagates to non-localStorage backends
|
|
156
|
+
(memory/indexedDB/cache), matching `set`/`remove`.
|
|
157
|
+
- **Failed `initialize()`** no longer caches the rejection permanently — a later
|
|
158
|
+
call can retry.
|
|
159
|
+
- **Query** — `$nin` now handles array-valued fields correctly; exclusion-mode
|
|
160
|
+
projection (`{ field: 0 }`) now actually excludes; projection paths are
|
|
161
|
+
prototype-pollution-safe. `clear({ expiredOnly })` now reclaims rows on SQLite.
|
|
162
|
+
- **Migration** — rolling back across a migration with no `down()` now throws
|
|
163
|
+
instead of silently lowering the stored version without reverting data.
|
|
164
|
+
- **TTL `expireAfter`** is now past-guarded like `expireAt`, and the pre-init
|
|
165
|
+
expiration fallback matches `TTLManager` precedence.
|
|
166
|
+
- **Cookie & Cache adapters** now use the shared serialize/deserialize, so
|
|
167
|
+
`Date`/`Map`/`Set` values round-trip with the same fidelity as localStorage.
|
|
168
|
+
- **Memory adapter** clones via `structuredClone`, so `Map`/`Set`/typed arrays
|
|
169
|
+
round-trip (its advertised `binary: true` now holds).
|
|
170
|
+
- **Cookie** rejects key names containing cookie-separator or control characters
|
|
171
|
+
(cookie-attribute / extra-cookie injection hardening).
|
|
172
|
+
|
|
173
|
+
### Documentation
|
|
174
|
+
|
|
175
|
+
- Rewrote the Docusaurus API reference and AI-agent docs to match the real API:
|
|
176
|
+
corrected the error-class hierarchy (all extend `StrataError`), the `query()`
|
|
177
|
+
data model (matches the decoded value's bare fields — wrapper fields aren't
|
|
178
|
+
queryable), TTL/sync/compression config field names, the `StorageChange` shape
|
|
179
|
+
(no `type` field), the real React/Vue hooks, and the valid import subpaths.
|
|
180
|
+
Removed inaccurate API references throughout the guides and examples.
|
|
181
|
+
- `llms-full.txt` is now regenerated by the docs `build` script (the `prebuild`
|
|
182
|
+
hook did not run under Yarn 4), so it cannot go stale.
|
|
183
|
+
|
|
184
|
+
## [2.7.0] - 2026-06-24
|
|
185
|
+
|
|
186
|
+
Audit-driven correctness and truthfulness release: documented behavior now
|
|
187
|
+
matches the code across the core engine, web/native adapters, and integrations.
|
|
188
|
+
|
|
189
|
+
### Fixed
|
|
190
|
+
- Combined `compress` + `encrypt` write/read pipeline now round-trips correctly.
|
|
191
|
+
- `clear({ olderThan })` is honored instead of being ignored.
|
|
192
|
+
- Key/value validation is enforced (invalid keys/values are rejected clearly).
|
|
193
|
+
- `close()` now resets internal state so the instance can be re-initialized.
|
|
194
|
+
- `import()` and `snapshot()`/`restore()` round-trip metadata (TTL, tags, etc.).
|
|
195
|
+
- Auto-backup no longer self-nests (backups of backups).
|
|
196
|
+
- `QueryOptions` (`limit`/`skip`/`sort`/`select`) are honored by `query()`.
|
|
197
|
+
- `query()` now decodes (deserialize/decompress/decrypt) returned results.
|
|
198
|
+
- Multi-adapter TTL cleanup runs across every registered adapter.
|
|
199
|
+
- Namespace key isolation is implemented (namespaced keys no longer collide).
|
|
200
|
+
- Encryption works in Node/SSR (no reliance on browser-only globals).
|
|
201
|
+
- Plugin web option forwarding: web plugin now forwards per-call options.
|
|
202
|
+
- `SessionStorageAdapter` uses the shared serialize helper (consistent encoding).
|
|
203
|
+
- iOS preferences are scoped to the plugin (no full `UserDefaults` domain wipe).
|
|
204
|
+
- Android secure storage rejects API < 23 with a clear error (secure storage
|
|
205
|
+
requires API 23+).
|
|
206
|
+
- Android filesystem adapter uses atomic writes (staging + rename).
|
|
207
|
+
- Android preferences/secure adapters round-trip the full `StorageValue` wrapper.
|
|
208
|
+
- `scripts/configure.js` ESM fix.
|
|
209
|
+
|
|
210
|
+
### Changed
|
|
211
|
+
- Default storage preference order is now persistent-first.
|
|
212
|
+
- **Compression is restricted to the `lz` algorithm** — `gzip` was never
|
|
213
|
+
implemented; the option type is now `algorithm?: 'lz'`.
|
|
214
|
+
- SQLite `transactional` flag is set to `false` (batch writes are best-effort,
|
|
215
|
+
not wrapped in a single transaction).
|
|
216
|
+
- Lint configuration split for clearer rule scoping.
|
|
217
|
+
- `firebase` is declared as an optional peer dependency.
|
|
218
|
+
- Added a `./package.json` entry to the package `exports` map.
|
|
219
|
+
|
|
220
|
+
### Removed
|
|
221
|
+
- Dead `strategy` config option and the unused `StorageStrategy` type
|
|
222
|
+
(type cleanup; this never affected runtime behavior).
|
|
223
|
+
|
|
224
|
+
### Security
|
|
225
|
+
- **Authenticated AES-CBC (Encrypt-then-MAC).** CBC-encrypted payloads now carry
|
|
226
|
+
an HMAC-SHA256 tag over `iv ‖ ciphertext` (computed with a separate,
|
|
227
|
+
domain-separated derived key) that is verified *before* decryption, closing a
|
|
228
|
+
ciphertext-malleability gap. **Breaking for pre-existing CBC ciphertexts
|
|
229
|
+
only**: data written before this release has no tag and now fails closed with
|
|
230
|
+
a clear "re-encrypt" error on read. **AES-GCM data — the default — is
|
|
231
|
+
unaffected.** Migration: re-encrypt affected values (read with the old build,
|
|
232
|
+
write with the new one) or switch them to GCM.
|
|
233
|
+
- **PBKDF2 default raised to 600,000 iterations** (was 100,000). Backward
|
|
234
|
+
compatible — the iteration count stored with each ciphertext is used on
|
|
235
|
+
decrypt, so existing data still opens.
|
|
236
|
+
- **Password no longer retained as a key-cache key** — derived-key cache entries
|
|
237
|
+
are keyed by a hash, not the raw passphrase.
|
|
238
|
+
- **`generatePassword` is now unbiased** (rejection sampling instead of modulo).
|
|
239
|
+
- **Cross-tab sync hardening** — origin IDs use `crypto.randomUUID()` and inbound
|
|
240
|
+
`BroadcastChannel` messages are validated before use.
|
|
241
|
+
- **Query `getNestedValue` matches own properties only** (no prototype-chain
|
|
242
|
+
traversal).
|
|
243
|
+
- **SQLite identifiers are validated and rejected, not sanitized.** `database`
|
|
244
|
+
and `table` (the only values that cannot be SQL-bound) must match
|
|
245
|
+
`^[A-Za-z_][A-Za-z0-9_]*$`; a non-conforming name is rejected with a clear
|
|
246
|
+
error at the public boundary instead of being silently stripped. The native
|
|
247
|
+
iOS/Android layers apply the same allow-list as defense-in-depth. All other
|
|
248
|
+
values remain bound parameters.
|
|
249
|
+
|
|
250
|
+
### Performance
|
|
251
|
+
- **SQLite `keys()`/`query()` no longer do an N+1 of native round-trips.** The
|
|
252
|
+
native layer filters expired rows in SQL and `query()` returns the full value
|
|
253
|
+
wrapper for every non-expired row in a single round-trip; the adapter dropped
|
|
254
|
+
its per-key `get()` loops. A new native `cleanupExpired` reclaims expired rows
|
|
255
|
+
in one `DELETE` on the TTL tick.
|
|
256
|
+
- **Native adapters skip the read-before-write when nobody is observing.**
|
|
257
|
+
`set()`/`remove()` only fetch the previous value (an extra bridge round-trip)
|
|
258
|
+
when a change subscriber is attached.
|
|
259
|
+
|
|
260
|
+
## [2.6.1] - 2026-05-29
|
|
261
|
+
|
|
262
|
+
### Documentation
|
|
263
|
+
- README and `AI-INTEGRATION-GUIDE.md` refreshed to surface the 2.6.0 features
|
|
264
|
+
that landed but were not yet covered in the bundled docs: SQLite multi-store
|
|
265
|
+
(`(database, table)` isolation), the native filesystem backend, and the
|
|
266
|
+
`size(true)` byte breakdown. Both now link the new
|
|
267
|
+
`docs/guides/platforms/device-verification.md`.
|
|
268
|
+
- The `package-polish-v2.5` tracker's `phase09.5` items are marked shipped
|
|
269
|
+
(delivered in 2.6.0); kept for resumable history.
|
|
270
|
+
|
|
271
|
+
### Maintenance
|
|
272
|
+
- Bumped 5 devDependencies to their latest patches: `@angular/common`,
|
|
273
|
+
`@angular/core`, `@angular/forms` 21.2.14 → 21.2.15;
|
|
274
|
+
`eslint-plugin-prettier` 5.5.5 → 5.5.6; `vue` 3.5.34 → 3.5.35. devDeps only,
|
|
275
|
+
no runtime change.
|
|
276
|
+
|
|
277
|
+
### Notes
|
|
278
|
+
- **No runtime or API change vs 2.6.0.** This release republishes the package
|
|
279
|
+
with up-to-date bundled documentation so consumers browsing npm see the
|
|
280
|
+
current feature set. The native iOS/Android code paths still require
|
|
281
|
+
on-device verification (see device-verification guide).
|
|
282
|
+
|
|
283
|
+
## [2.6.0] - 2026-05-27
|
|
284
|
+
|
|
285
|
+
### Added
|
|
286
|
+
- **SQLite multi-store** — the `database` and `table` options are now honored on
|
|
287
|
+
iOS and Android, so multiple independent SQLite stores (distinct database files
|
|
288
|
+
and/or tables) no longer collapse into a single physical table. Use separate
|
|
289
|
+
`defineStorage` instances (or distinct `database`/`table` config) to keep
|
|
290
|
+
stores isolated.
|
|
291
|
+
- **Native filesystem backend** — `FilesystemAdapter` now works on iOS and
|
|
292
|
+
Android (it was previously unavailable on every platform). One file per key
|
|
293
|
+
under the app's documents/files directory (`strata_storage/`), storing the full
|
|
294
|
+
value wrapper as JSON, with atomic writes; `isAvailable()` now returns `true`.
|
|
295
|
+
- **`size(true)`** — native SQLite and filesystem backends now
|
|
296
|
+
return the `{ keys, values, metadata }` byte breakdown (the flag was previously
|
|
297
|
+
ignored, returning only `{ total, count }`).
|
|
298
|
+
|
|
299
|
+
### Fixed
|
|
300
|
+
- **SQLite value round-trip** — native `get` now returns the full `StorageValue`
|
|
301
|
+
wrapper (`{ value, created, updated, expires, tags, metadata }`) instead of a
|
|
302
|
+
raw blob, so TTL, tags, and metadata survive a write→read cycle on iOS and
|
|
303
|
+
Android. Corrupt/legacy rows are treated as a miss instead of throwing.
|
|
304
|
+
- **Filesystem key/temp-file collision** — in-flight temp files now live in a
|
|
305
|
+
reserved staging subdirectory, so a key whose name resembles a temp file (e.g.
|
|
306
|
+
`"backup.tmp"`) is never skipped by `keys()`/`size()` or wrongly deleted by
|
|
307
|
+
`clear()`.
|
|
308
|
+
- **`size().total` consistency** — native backends now include key bytes in
|
|
309
|
+
`total`, matching the web adapters' convention.
|
|
310
|
+
- **iOS SQLite bind safety** — text/blob binds use `SQLITE_TRANSIENT`, removing a
|
|
311
|
+
latent use-after-free for transient Swift buffers.
|
|
312
|
+
|
|
313
|
+
### Changed
|
|
314
|
+
- **`androidx.security:security-crypto`** upgraded `1.1.0-alpha06` → `1.1.0`
|
|
315
|
+
(stable). The `EncryptedSharedPreferences` / `MasterKey` API is unchanged.
|
|
316
|
+
- The native SQLite database file now resolves from the `database` option
|
|
317
|
+
(default `strata_storage` → `strata_storage.db`); table identifiers are
|
|
318
|
+
sanitized to `[A-Za-z0-9_]`. Stored values remain bound parameters.
|
|
319
|
+
- Marketing website tooling migrated to Yarn 4 (Corepack).
|
|
320
|
+
|
|
321
|
+
### Notes
|
|
322
|
+
- The native iOS/Android changes in this release are code-complete and reviewed
|
|
323
|
+
but require on-device verification — follow
|
|
324
|
+
`docs/guides/platforms/device-verification.md`. Web/browser functionality is
|
|
325
|
+
validated by the quality gates (typecheck + build + lint); the project ships no
|
|
326
|
+
automated test runner.
|
|
327
|
+
|
|
328
|
+
## [2.5.0] - 2026-05-26
|
|
329
|
+
|
|
330
|
+
### Added
|
|
331
|
+
- **Framework-agnostic, provider-free usage** — `defineStorage()` returns a
|
|
332
|
+
ready-to-use instance you can create once and use anywhere, with no
|
|
333
|
+
Provider/DI required (Zustand-style). `createStrataHooks(instance)` (React),
|
|
334
|
+
`createStrataComposables(instance)` (Vue), and `provideStrata(instance)`
|
|
335
|
+
(Angular) bind to a created instance; the Provider/Plugin/Service APIs remain
|
|
336
|
+
optional.
|
|
337
|
+
- **Synchronous API** — `getSync`/`setSync`/`removeSync`/`hasSync`/`keysSync`/
|
|
338
|
+
`clearSync` for sync-capable adapters (memory, localStorage, sessionStorage,
|
|
339
|
+
cookies, url). Async-only backends (indexedDB, cache, native) throw a clear
|
|
340
|
+
error; sync set with encrypt/compress also throws (those are async).
|
|
341
|
+
- **URL-state adapter** (`URLAdapter`) — persist state in the query string
|
|
342
|
+
(default) or hash fragment, with `popstate`/`hashchange` change events.
|
|
343
|
+
- **Disaster recovery** (all opt-in) — FNV-1a integrity checksums with
|
|
344
|
+
corruption detection, durable write-verify-readback, mirroring to backup
|
|
345
|
+
adapters with read-repair, and `snapshot()`/`restore()` plus scheduled
|
|
346
|
+
`autoBackup`.
|
|
347
|
+
- Exported integrity helpers (`computeChecksum`/`verifyChecksum`) and error
|
|
348
|
+
classes (e.g. `IntegrityError`) for `instanceof` use.
|
|
349
|
+
|
|
350
|
+
### Fixed
|
|
351
|
+
- **The React/Vue/Angular entry points are now actually built and shipped** —
|
|
352
|
+
`strata-storage/react|vue|angular` previously resolved to files that were
|
|
353
|
+
never compiled into `dist/`, so every framework import failed.
|
|
354
|
+
- Multi-adapter operations (`keys`/`clear`/`size`/`subscribe` with no explicit
|
|
355
|
+
`storage`) now span all registered adapters instead of only the default.
|
|
356
|
+
- Cross-tab sync now applies received changes to local memory/IndexedDB/cache
|
|
357
|
+
adapters (previously broadcasts were sent but never applied).
|
|
358
|
+
- AES-CBC now uses a correct 16-byte IV.
|
|
359
|
+
- Security: prototype-pollution guards in deep-merge/import/restore, ReDoS-capped
|
|
360
|
+
regex, and `SameSite=Lax` + automatic `Secure` cookie defaults.
|
|
361
|
+
- iOS native plugin now registers with Capacitor (it had no registration and was
|
|
362
|
+
non-functional); added missing native methods on iOS and Android; Keychain
|
|
363
|
+
accessibility hardened.
|
|
364
|
+
|
|
365
|
+
### Changed
|
|
366
|
+
- All diagnostic output now routes through a level-gated internal logger
|
|
367
|
+
(default `warn`); the library no longer writes to the consumer console by
|
|
368
|
+
default. Toggle with `new Strata({ debug: { enabled: true } })`.
|
|
369
|
+
- Dependencies updated to latest stable (including TypeScript 6 and ESLint 10).
|
|
370
|
+
The default instance initializes lazily, so importing the package performs no
|
|
371
|
+
I/O. Current quality gates are typecheck, build, lint, and CI; the project no
|
|
372
|
+
longer ships an automated test runner.
|
|
373
|
+
|
|
374
|
+
## [2.1.0] - 2024-01-30
|
|
375
|
+
|
|
376
|
+
### Added
|
|
377
|
+
- Complete native iOS implementation (Swift)
|
|
378
|
+
- Complete native Android implementation (Java)
|
|
379
|
+
- Enhanced error messages for platform-specific functions
|
|
380
|
+
- Comprehensive JSDoc documentation for all public APIs
|
|
381
|
+
- Pattern matching support for `keys()` and `clear()` methods
|
|
382
|
+
- Prefix support for clearing storage
|
|
383
|
+
- Apache 2.0 license with patent protection
|
|
384
|
+
- Security policy (SECURITY.md)
|
|
385
|
+
- Contributing guidelines (CONTRIBUTING.md)
|
|
386
|
+
- Support documentation (SUPPORT.md)
|
|
387
|
+
- Code of Conduct
|
|
388
|
+
- Issue templates
|
|
389
|
+
|
|
390
|
+
### Fixed
|
|
391
|
+
- iOS and Android method signature consistency
|
|
392
|
+
- Android constructor issues for SharedPreferences and EncryptedStorage
|
|
393
|
+
- TypeScript type warnings throughout codebase
|
|
394
|
+
- Platform detection for Capacitor environment
|
|
395
|
+
- Web plugin error messages now suggest alternatives
|
|
396
|
+
|
|
397
|
+
### Changed
|
|
398
|
+
- License from MIT to Apache 2.0
|
|
399
|
+
- Documentation moved to organized folders (.github/, docs/)
|
|
400
|
+
- Improved README with comprehensive feature links
|
|
401
|
+
- Project status updated to "Production Ready"
|
|
402
|
+
|
|
403
|
+
### Documentation
|
|
404
|
+
- Added caching patterns guide
|
|
405
|
+
- Added session management patterns
|
|
406
|
+
- Added TTL feature documentation
|
|
407
|
+
- Enhanced all adapter documentation
|
|
408
|
+
- Improved API reference with examples
|
|
409
|
+
|
|
410
|
+
## [2.0.4] - 2024-01-29
|
|
411
|
+
|
|
412
|
+
### Added
|
|
413
|
+
- Provider-less architecture (like Zustand)
|
|
414
|
+
- Zero-dependency implementation
|
|
415
|
+
- Dynamic adapter loading
|
|
416
|
+
- Comprehensive documentation structure
|
|
417
|
+
|
|
418
|
+
### Fixed
|
|
419
|
+
- Bundle size optimizations
|
|
420
|
+
- Tree-shaking improvements
|
|
421
|
+
|
|
422
|
+
## [2.0.2] - 2024-01-28
|
|
423
|
+
|
|
424
|
+
### Fixed
|
|
425
|
+
- Added missing LICENSE file
|
|
426
|
+
- Added .npmignore file to exclude unnecessary files from npm package
|
|
427
|
+
|
|
428
|
+
## [2.0.1] - 2025-08-06
|
|
429
|
+
|
|
430
|
+
### Fixed
|
|
431
|
+
- Fixed BaseAdapter and StorageAdapter interface mismatch where `subscribe` and `close` methods were incorrectly marked as optional
|
|
432
|
+
- Fixed adapter initialization flow to prevent double initialization
|
|
433
|
+
- Fixed "No available storage adapters found" error by improving adapter detection and initialization
|
|
434
|
+
- Memory adapter now correctly works as fallback
|
|
435
|
+
- Improved error messages to show which adapters were tried and which are registered
|
|
436
|
+
|
|
437
|
+
### Added
|
|
438
|
+
- Complete React + Capacitor example app with comprehensive testing interface
|
|
439
|
+
- Test coverage for all web storage adapters (Memory, LocalStorage, SessionStorage, IndexedDB, Cache, Cookies)
|
|
440
|
+
- Visual test interface showing real-time operation status
|
|
441
|
+
- Support for Android and iOS platforms in example app
|
|
442
|
+
|
|
443
|
+
### Changed
|
|
444
|
+
- Default storage preference order now includes multiple fallbacks: memory, localStorage, sessionStorage, indexedDB
|
|
445
|
+
- Singleton storage instance now properly initializes on first use
|
|
446
|
+
- Better TypeScript types for storage operations
|
|
447
|
+
|
|
448
|
+
### Documentation
|
|
449
|
+
- Added comprehensive example app documentation
|
|
450
|
+
- Updated README with link to working example
|
|
451
|
+
- Added test results showing all adapters working correctly
|
|
452
|
+
|
|
453
|
+
## [2.0.0] - Initial 2.x release
|
|
454
|
+
- Initial implementation of Strata Storage
|
|
455
|
+
- Zero-dependency architecture
|
|
456
|
+
- Universal storage API
|
|
457
|
+
- Multiple adapter support
|