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 +21 -0
- package/README.md +209 -0
- package/dist/drivers/indexeddb.d.ts +4 -0
- package/dist/drivers/indexeddb.d.ts.map +1 -0
- package/dist/drivers/indexeddb.js +863 -0
- package/dist/drivers/localstorage.d.ts +4 -0
- package/dist/drivers/localstorage.d.ts.map +1 -0
- package/dist/drivers/localstorage.js +209 -0
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/localspace.d.ts +42 -0
- package/dist/localspace.d.ts.map +1 -0
- package/dist/localspace.js +414 -0
- package/dist/types.d.ts +227 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/utils/helpers.d.ts +33 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +120 -0
- package/dist/utils/serializer.d.ts +4 -0
- package/dist/utils/serializer.d.ts.map +1 -0
- package/dist/utils/serializer.js +199 -0
- package/package.json +80 -6
- package/src/drivers/indexeddb.ts +1110 -0
- package/src/drivers/localstorage.ts +329 -0
- package/src/index.ts +37 -0
- package/src/localspace.ts +607 -0
- package/src/types.ts +297 -0
- package/src/utils/helpers.ts +182 -0
- package/src/utils/serializer.ts +230 -0
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
|
+

|
|
4
|
+
[](https://www.npmjs.com/package/localspace)
|
|
5
|
+

|
|
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 @@
|
|
|
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"}
|