localspace 0.0.1 → 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Michael Lin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,209 @@
1
+ # localspace
2
+
3
+ ![Node CI](https://github.com/unadlib/localspace/workflows/Node%20CI/badge.svg)
4
+ [![npm](https://img.shields.io/npm/v/localspace.svg)](https://www.npmjs.com/package/localspace)
5
+ ![license](https://img.shields.io/npm/l/localspace)
6
+
7
+ localspace — modern storage toolkit that keeps localForage compatibility while using async/await, TypeScript, and zero legacy baggage.
8
+
9
+ ## Motivation
10
+
11
+ The industry still leans on localForage’s familiar API, yet modern apps crave stronger typing, async ergonomics, and multi-platform reliability without a painful rewrite. localspace exists to bridge that gap: it honors the old contract while delivering the capabilities teams have been asking for since 2021.
12
+
13
+ ### What needed to change
14
+
15
+ localForage’s storage layer stopped evolving while real-world needs kept growing. Long-standing requests—first-class TypeScript types, native async/await, reliable IndexedDB cleanup, consistency across Node and React Native, batch operations, TTL, and encryption—remain unresolved. Teams want those upgrades without abandoning the API that already powers their products.
16
+
17
+ ### How localspace responds
18
+
19
+ We stay 100% compatible with localForage on the surface, but rebuild the internals with modern JavaScript, a TypeScript-first type system, native Promises, and a clean driver architecture. That drop-in approach delivers predictable behavior (including a complete IndexedDB `dropInstance`), clearer diagnostics, and room to grow with new drivers (Cache API, SQLite, OPFS) and optional plugins (TTL, encryption, compression) across browsers, Node, React Native, and Electron. Our goal is a storage toolkit that preserves your investment in the localForage mental model while finally addressing the community’s accumulated pain points.
20
+
21
+ ### Why rebuild instead of fork?
22
+
23
+ Starting fresh let us eliminate technical debt while maintaining API compatibility. The codebase is written in modern TypeScript, uses contemporary patterns, and has a clear structure that makes it straightforward to add new capabilities. Teams can migrate from localForage without changing application code, then unlock better developer experience and future extensibility.
24
+
25
+ ## Table of Contents
26
+ - [Motivation](#motivation)
27
+ - [What needed to change](#what-needed-to-change)
28
+ - [How localspace responds](#how-localspace-responds)
29
+ - [Why rebuild instead of fork?](#why-rebuild-instead-of-fork)
30
+ - [Roadmap](#roadmap)
31
+ - [Installation and Usage](#installation-and-usage)
32
+ - [localspace delivers modern storage compatibility](#localspace-delivers-modern-storage-compatibility)
33
+ - [Install and import localspace](#install-and-import-localspace)
34
+ - [Store data with async flows or callbacks](#store-data-with-async-flows-or-callbacks)
35
+ - [Configure isolated stores for clear data boundaries](#configure-isolated-stores-for-clear-data-boundaries)
36
+ - [Choose drivers with predictable fallbacks](#choose-drivers-with-predictable-fallbacks)
37
+ - [Handle binary data across browsers](#handle-binary-data-across-browsers)
38
+ - [Migration Guide](#migration-guide)
39
+ - [Note differences from localForage before upgrading](#note-differences-from-localforage-before-upgrading)
40
+ - [Enable compatibility mode for legacy callbacks](#enable-compatibility-mode-for-legacy-callbacks)
41
+ - [Troubleshooting](#troubleshooting)
42
+ - [License](#license)
43
+
44
+ ## Roadmap
45
+
46
+ localspace is built on a foundation designed for growth. Here's what's planned:
47
+
48
+ ### Core Compatibility (Complete)
49
+ - [x] IndexedDB and localStorage drivers
50
+ - [x] Full localForage API parity
51
+ - [x] TypeScript-first implementation
52
+ - [x] Comprehensive test coverage
53
+ - [x] Modern build pipeline (ES modules, CommonJS, UMD)
54
+
55
+ ### TODO
56
+ - [ ] **Batch operations** - `setItems()`, `getItems()`, `removeItems()` for better performance
57
+ - [ ] **Improved error handling** - Structured error types with detailed context
58
+ - [ ] **Performance optimizations** - Connection pooling, transaction batching
59
+ - [ ] **Plugin system** - Middleware architecture for cross-cutting concerns
60
+ - [ ] **Cache API driver** - Native browser caching with automatic HTTP semantics
61
+ - [ ] **OPFS driver** - Origin Private File System for high-performance file storage
62
+ - [ ] **Memory driver** - In-memory storage for testing and SSR
63
+ - [ ] **Custom driver templates** - Documentation and examples for third-party drivers
64
+ - [ ] **Node.js** - File system and SQLite adapters
65
+ - [ ] **React Native** - AsyncStorage and SQLite drivers
66
+ - [ ] **Electron** - Main and renderer process coordination
67
+ - [ ] **Deno** - Native KV store integration
68
+ - [ ] **TTL plugin** - Time-to-live expiration with automatic cleanup
69
+ - [ ] **Encryption plugin** - Transparent encryption/decryption with Web Crypto API
70
+ - [ ] **Compression plugin** - LZ-string or Brotli compression for large values
71
+ - [ ] **Sync plugin** - Multi-tab synchronization with BroadcastChannel
72
+ - [ ] **Quota plugin** - Automatic quota management and cleanup strategies
73
+
74
+ ### 📊 Community Priorities
75
+
76
+ We prioritize features based on community feedback. If you need a specific capability:
77
+
78
+ 1. **Check existing issues** to see if it's already requested
79
+ 2. **Open a feature request** with your use case and requirements
80
+ 3. **Contribute** - We welcome PRs for new drivers, plugins, or improvements
81
+
82
+ **Want to help?** The most impactful contributions right now:
83
+ - Testing in diverse environments (browsers, frameworks, edge cases)
84
+ - Documentation improvements and usage examples
85
+ - Performance benchmarks and optimization suggestions
86
+ - New driver implementations (especially Cache API and OPFS)
87
+
88
+ ## Installation and Usage
89
+
90
+ ### localspace delivers modern storage compatibility
91
+ localspace targets developers who need localForage's API surface without its historical baggage. **You get the same method names, configuration options, and driver constants, all implemented with modern JavaScript and TypeScript types.**
92
+
93
+ - Promise-first API with optional callbacks
94
+ - IndexedDB and localStorage drivers included out of the box
95
+ - ES module, CommonJS, and UMD bundles plus `.d.ts` files
96
+ - Drop-in TypeScript generics for value typing
97
+
98
+ ### Install and import localspace
99
+ Install the package with your preferred package manager and import it once at the entry point where you manage storage.
100
+
101
+ ```bash
102
+ npm install localspace
103
+ # or
104
+ yarn add localspace
105
+ # or
106
+ pnpm add localspace
107
+ ```
108
+
109
+ ```ts
110
+ import localspace from 'localspace';
111
+ ```
112
+
113
+ ### Store data with async flows or callbacks
114
+ Use async/await for the clearest flow. **Callbacks remain supported for parity with existing localForage codebases.**
115
+
116
+ ```ts
117
+ await localspace.setItem('user', { name: 'Ada', role: 'admin' });
118
+ const user = await localspace.getItem<{ name: string; role: string }>('user');
119
+
120
+ localspace.getItem('user', (error, value) => {
121
+ if (error) return console.error(error);
122
+ console.log(value?.name);
123
+ });
124
+ ```
125
+
126
+ ### Configure isolated stores for clear data boundaries
127
+ Create independent instances when you want to separate cache layers or product features. Each instance can override defaults like `name`, `storeName`, and driver order.
128
+
129
+ ```ts
130
+ const sessionCache = localspace.createInstance({
131
+ name: 'session',
132
+ storeName: 'volatile-items',
133
+ });
134
+
135
+ await sessionCache.setItem('token', 'abc123');
136
+ ```
137
+
138
+ ### Choose drivers with predictable fallbacks
139
+ By default, localspace prefers IndexedDB (`INDEXEDDB`) and falls back to localStorage (`LOCALSTORAGE`). Configure alternative sequences as needed.
140
+
141
+ ```ts
142
+ await localspace.setDriver([localspace.INDEXEDDB, localspace.LOCALSTORAGE]);
143
+
144
+ if (!localspace.supports(localspace.INDEXEDDB)) {
145
+ console.warn('IndexedDB unavailable, using localStorage wrapper.');
146
+ }
147
+ ```
148
+
149
+ **Tip:** Use `defineDriver()` and `getDriver()` to register custom drivers that match the localForage interface.
150
+
151
+ ### Handle binary data across browsers
152
+ localspace serializes complex values transparently. It stores `Blob`, `ArrayBuffer`, and typed arrays in IndexedDB natively and in localStorage via Base64 encoding when necessary. You write the same code regardless of the driver.
153
+
154
+ ```ts
155
+ const file = new Blob(['hello'], { type: 'text/plain' });
156
+ await localspace.setItem('file', file);
157
+ const restored = await localspace.getItem<Blob>('file');
158
+ ```
159
+
160
+ ## Migration Guide
161
+
162
+ ### Note differences from localForage before upgrading
163
+ - `dropInstance()` throws a real `Error` when arguments are invalid. Examine `error.message` instead of comparing string literals.
164
+ - Blob capability checks run on each request instead of being cached. Cache the result in your application if repeated blob writes dominate your workload.
165
+ - **WebSQL is intentionally unsupported.** Migrate any WebSQL-only code to IndexedDB or localStorage before switching.
166
+
167
+ ### Enable compatibility mode for driver setup methods
168
+ If you maintain older code that expects separate *success* and *error* callbacks for driver setup methods (`setDriver`, `defineDriver`), enable `compatibilityMode` when creating an instance. **Use this mode only for migrations; prefer native Promises going forward.**
169
+
170
+ ```ts
171
+ const legacy = localspace.createInstance({
172
+ name: 'legacy-store',
173
+ storeName: 'pairs',
174
+ compatibilityMode: true,
175
+ });
176
+
177
+ legacy.setDriver(
178
+ [legacy.LOCALSTORAGE],
179
+ () => {
180
+ // Success callback receives no arguments.
181
+ },
182
+ (error) => {
183
+ // Error callback receives the Error object only.
184
+ },
185
+ );
186
+ ```
187
+
188
+ **Note:** Storage methods like `setItem`, `getItem`, `removeItem`, etc. always use Node-style `(error, value)` callbacks regardless of `compatibilityMode`. This matches localForage's original behavior. For example:
189
+
190
+ ```ts
191
+ localspace.setItem('key', 'value', (err, value) => {
192
+ if (err) {
193
+ console.error('Error:', err);
194
+ } else {
195
+ console.log('Saved:', value);
196
+ }
197
+ });
198
+ ```
199
+
200
+ When `compatibilityMode` is off, driver setup methods also use Node-style callbacks. Promises are recommended for all new code.
201
+
202
+ ## Troubleshooting
203
+ - **Wait for readiness:** Call `await localspace.ready()` before the first operation when you need to confirm driver selection.
204
+ - **Inspect drivers:** Use `localspace.driver()` to confirm which driver is active in different environments.
205
+ - **Handle quota errors:** Catch `DOMException` errors from `setItem` to inform users about storage limits.
206
+ - **Run unit tests:** The project ships with Vitest and Playwright suites covering API behavior; run `yarn test` to verify changes.
207
+
208
+ ## License
209
+ [MIT](./LICENSE)
@@ -0,0 +1,4 @@
1
+ import type { Driver } from '../types';
2
+ declare const asyncStorage: Driver;
3
+ export default asyncStorage;
4
+ //# sourceMappingURL=indexeddb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexeddb.d.ts","sourceRoot":"","sources":["../../src/drivers/indexeddb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAKP,MAAM,UAAU,CAAC;AAgkClB,QAAA,MAAM,YAAY,EAAE,MAanB,CAAC;AAEF,eAAe,YAAY,CAAC"}