tiny-idb 1.2.0 → 1.3.0
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/README.md +55 -10
- package/index.d.ts +78 -0
- package/package.json +7 -3
- package/tiny-idb.js +9 -14
- package/tiny-idb.min.js +2 -1
package/README.md
CHANGED
|
@@ -2,12 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
**A minimalist, high-performance IndexedDB wrapper for modern web applications.**
|
|
4
4
|
|
|
5
|
-
`tiny-idb` provides a non-blocking, asynchronous alternative to `localStorage`.
|
|
5
|
+
`tiny-idb` provides a non-blocking, asynchronous alternative to `localStorage`. While `localStorage` is capped at ~5-10MB and can be cleared by the browser under memory pressure, `tiny-idb` leverages IndexedDB to offer virtually unlimited storage (up to 80% of disk space) with much higher durability.
|
|
6
|
+
|
|
7
|
+
It is designed for developers who require the reliability and capacity of IndexedDB without the complexity of its native API. By focusing on a single-store, key-value architecture, it eliminates the need for database versioning and boilerplate configuration.
|
|
6
8
|
|
|
7
9
|
[](https://www.npmjs.com/package/tiny-idb)
|
|
8
10
|
[](LICENSE)
|
|
9
11
|
[](https://bundlephobia.com/package/tiny-idb)
|
|
10
12
|
|
|
13
|
+
## Why tiny-idb?
|
|
14
|
+
|
|
15
|
+
There are many IndexedDB wrappers, but `tiny-idb` is built with a specific philosophy: **Smallest possible footprint without sacrificing data integrity.**
|
|
16
|
+
|
|
17
|
+
- **Smaller than most icons**: At less than 1KB (gzipped), it's lighter than a 16x16 PNG.
|
|
18
|
+
- **Atomic Operations**: Built-in `update`, `push`, and `merge` are ACID-compliant and race-condition safe. No more partial updates or data loss.
|
|
19
|
+
- **Zero dependencies**: Built on pure vanilla JS. No external bloat.
|
|
20
|
+
- **Drop-in localStorage replacement**: Use the same `getItem`, `setItem`, `removeItem` calls, but with `await`.
|
|
21
|
+
|
|
11
22
|
## Core Advantages
|
|
12
23
|
|
|
13
24
|
### Architectural Simplicity
|
|
@@ -44,13 +55,14 @@ npm install tiny-idb
|
|
|
44
55
|
|
|
45
56
|
## Technical Comparison
|
|
46
57
|
|
|
47
|
-
| Feature | localStorage | tiny-idb |
|
|
58
|
+
| Feature | `localStorage` | `tiny-idb` |
|
|
48
59
|
|---------|--------------|----------|
|
|
49
60
|
| **Execution** | Synchronous (Blocks UI) | Asynchronous (Non-blocking) |
|
|
50
|
-
| **Storage Limit** | ~5-10MB | Virtually unlimited (
|
|
51
|
-
| **Data Types** | Strings only | Objects, Blobs, Arrays, Numbers |
|
|
61
|
+
| **Storage Limit** | ~5-10MB (Fixed) | Virtually unlimited (80%+ of disk) |
|
|
62
|
+
| **Data Types** | Strings only (Requires `JSON.parse`) | Objects, Blobs, Arrays, Numbers, Files |
|
|
52
63
|
| **Data Integrity** | Basic | ACID Compliant |
|
|
53
64
|
| **Race Condition Safety** | None | Atomic `update`/`push`/`merge` |
|
|
65
|
+
| **Tab Sync** | No | Automatic |
|
|
54
66
|
|
|
55
67
|
## API Reference
|
|
56
68
|
|
|
@@ -63,13 +75,24 @@ npm install tiny-idb
|
|
|
63
75
|
| `clear()` | Removes all data from the store. |
|
|
64
76
|
| `keys()` | Returns an array of all keys. |
|
|
65
77
|
| `values()` | Returns an array of all values. |
|
|
78
|
+
| `entries()` | Returns an array of `[key, value]` pairs. |
|
|
66
79
|
| `count()` | Returns the total number of entries. |
|
|
67
|
-
| `update(key, fn)` | Performs an atomic read-modify-write
|
|
68
|
-
| `push(key, value)` | Atomically appends
|
|
69
|
-
| `merge(key, patch)` | Atomically shallow-merges an object. |
|
|
80
|
+
| `update(key, fn)` | Performs an **atomic** read-modify-write. |
|
|
81
|
+
| `push(key, value)` | **Atomically** appends to an array. |
|
|
82
|
+
| `merge(key, patch)` | **Atomically** shallow-merges an object. |
|
|
70
83
|
|
|
71
84
|
## Example Use Cases
|
|
72
85
|
|
|
86
|
+
### Iterating over Data
|
|
87
|
+
Use `entries()` to easily process all stored key-value pairs.
|
|
88
|
+
```javascript
|
|
89
|
+
const allEntries = await tinyIDB.entries();
|
|
90
|
+
|
|
91
|
+
for (const [key, value] of allEntries) {
|
|
92
|
+
console.log(`${key}:`, value);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
73
96
|
### User Settings Management
|
|
74
97
|
Easily manage and update partial user preferences without worrying about race conditions.
|
|
75
98
|
```javascript
|
|
@@ -84,6 +107,19 @@ await tinyIDB.merge('settings', { notifications: false, language: 'en' });
|
|
|
84
107
|
// Result: { theme: 'dark', notifications: false, language: 'en' }
|
|
85
108
|
```
|
|
86
109
|
|
|
110
|
+
### Storing Binary Data (Blobs/Files)
|
|
111
|
+
Unlike `localStorage`, `tiny-idb` can store binary data directly.
|
|
112
|
+
```javascript
|
|
113
|
+
const response = await fetch('/profile-picture.jpg');
|
|
114
|
+
const blob = await response.blob();
|
|
115
|
+
|
|
116
|
+
await tinyIDB.set('user_avatar', blob);
|
|
117
|
+
|
|
118
|
+
// Later...
|
|
119
|
+
const avatar = await tinyIDB.get('user_avatar');
|
|
120
|
+
document.querySelector('img').src = URL.createObjectURL(avatar);
|
|
121
|
+
```
|
|
122
|
+
|
|
87
123
|
### Persistent Shopping Cart
|
|
88
124
|
Atomically add items to a list, ensuring no items are lost during concurrent updates.
|
|
89
125
|
```javascript
|
|
@@ -100,7 +136,7 @@ Safely increment values using the `update` method.
|
|
|
100
136
|
```javascript
|
|
101
137
|
await tinyIDB.set('page_views', 0);
|
|
102
138
|
|
|
103
|
-
// Increment safely
|
|
139
|
+
// Increment safely - even if multiple tabs do it at once
|
|
104
140
|
await tinyIDB.update('page_views', count => (count || 0) + 1);
|
|
105
141
|
```
|
|
106
142
|
|
|
@@ -134,6 +170,15 @@ await settings.set('theme', 'dark');
|
|
|
134
170
|
await cache.set('temp_data', { id: 1 });
|
|
135
171
|
```
|
|
136
172
|
|
|
173
|
+
## Browser Support
|
|
174
|
+
|
|
175
|
+
`tiny-idb` targets modern browsers that support:
|
|
176
|
+
- [IndexedDB](https://caniuse.com/indexeddb) (98%+)
|
|
177
|
+
- [ES Modules](https://caniuse.com/es6-module)
|
|
178
|
+
- [Async/Await](https://caniuse.com/async-functions)
|
|
179
|
+
|
|
180
|
+
If you need to support legacy browsers (IE11), you will need to transpile and polyfill.
|
|
181
|
+
|
|
137
182
|
## Development
|
|
138
183
|
|
|
139
184
|
`tiny-idb` is written in pure vanilla JavaScript. No compilation is required for development.
|
|
@@ -148,10 +193,10 @@ npm test
|
|
|
148
193
|
npm run test:min
|
|
149
194
|
```
|
|
150
195
|
|
|
151
|
-
### Minification
|
|
196
|
+
### Building & Minification
|
|
152
197
|
Generate the production-ready minified file:
|
|
153
198
|
```bash
|
|
154
|
-
npm run
|
|
199
|
+
npm run build
|
|
155
200
|
```
|
|
156
201
|
|
|
157
202
|
## License
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** tiny-idb - MIT © Jelodar */
|
|
2
|
+
|
|
3
|
+
export interface TinyIDBInstance {
|
|
4
|
+
/**
|
|
5
|
+
* Creates or retrieves a cached instance of a database and store.
|
|
6
|
+
* @param dbName Name of the IndexedDB database.
|
|
7
|
+
* @param storeName Name of the object store (defaults to dbName).
|
|
8
|
+
*/
|
|
9
|
+
open(dbName: string, storeName?: string): TinyIDBInstance;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Persists a value to the store.
|
|
13
|
+
*/
|
|
14
|
+
set(key: any, value: any): Promise<void>;
|
|
15
|
+
/** Alias for set() */
|
|
16
|
+
setItem(key: any, value: any): Promise<void>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Retrieves a value; returns undefined if not found.
|
|
20
|
+
*/
|
|
21
|
+
get<T = any>(key: any): Promise<T | undefined>;
|
|
22
|
+
/** Alias for get() */
|
|
23
|
+
getItem<T = any>(key: any): Promise<T | undefined>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Deletes a specific key.
|
|
27
|
+
*/
|
|
28
|
+
remove(key: any): Promise<void>;
|
|
29
|
+
/** Alias for remove() */
|
|
30
|
+
removeItem(key: any): Promise<void>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Removes all data from the store.
|
|
34
|
+
*/
|
|
35
|
+
clear(): Promise<void>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Returns an array of all keys.
|
|
39
|
+
*/
|
|
40
|
+
keys(): Promise<any[]>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns an array of all values.
|
|
44
|
+
*/
|
|
45
|
+
values<T = any>(): Promise<T[]>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Returns an array of [key, value] pairs.
|
|
49
|
+
*/
|
|
50
|
+
entries<K = any, V = any>(): Promise<[K, V][]>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Returns the total number of entries.
|
|
54
|
+
*/
|
|
55
|
+
count(): Promise<number>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Performs an atomic read-modify-write operation within a single transaction.
|
|
59
|
+
* Note: The function 'fn' must be synchronous or microtask-only (no await on fetch/setTimeout)
|
|
60
|
+
* to prevent the IndexedDB transaction from auto-committing.
|
|
61
|
+
* @param key The key to update.
|
|
62
|
+
* @param fn A function that receives the current value and returns the new value.
|
|
63
|
+
*/
|
|
64
|
+
update<T = any>(key: any, fn: (currentValue: T | undefined) => T | Promise<T>): Promise<void>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Atomically appends a value to an array. Initializes as [value] if key doesn't exist.
|
|
68
|
+
*/
|
|
69
|
+
push(key: any, value: any): Promise<void>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Atomically shallow-merges an object. Initializes as patch if key doesn't exist.
|
|
73
|
+
*/
|
|
74
|
+
merge(key: any, patch: object): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const tinyIDB: TinyIDBInstance;
|
|
78
|
+
export default tinyIDB;
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiny-idb",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "An extremely fast, super simple, and dependency-free IndexedDB wrapper. A drop-in replacement for localStorage with reliability and durability.",
|
|
5
5
|
"main": "tiny-idb.js",
|
|
6
6
|
"module": "tiny-idb.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
7
8
|
"type": "module",
|
|
8
9
|
"repository": {
|
|
9
10
|
"type": "git",
|
|
@@ -19,7 +20,8 @@
|
|
|
19
20
|
"browser",
|
|
20
21
|
"persistent",
|
|
21
22
|
"nosql",
|
|
22
|
-
"key-value"
|
|
23
|
+
"key-value",
|
|
24
|
+
"typescript"
|
|
23
25
|
],
|
|
24
26
|
"author": "Jelodar",
|
|
25
27
|
"license": "MIT",
|
|
@@ -30,6 +32,7 @@
|
|
|
30
32
|
"files": [
|
|
31
33
|
"tiny-idb.js",
|
|
32
34
|
"tiny-idb.min.js",
|
|
35
|
+
"index.d.ts",
|
|
33
36
|
"LICENSE",
|
|
34
37
|
"README.md"
|
|
35
38
|
],
|
|
@@ -40,6 +43,7 @@
|
|
|
40
43
|
"scripts": {
|
|
41
44
|
"test": "node test.js",
|
|
42
45
|
"test:min": "TEST_MIN=1 node test.js",
|
|
43
|
-
"
|
|
46
|
+
"build": "npm run minify",
|
|
47
|
+
"minify": "terser tiny-idb.js -o tiny-idb.min.js -c toplevel,unsafe -m toplevel --comments '/tiny-idb/'"
|
|
44
48
|
}
|
|
45
49
|
}
|
package/tiny-idb.js
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* tiny-idb - A super simple, fast, and dependency-free IndexedDB wrapper.
|
|
3
|
-
* Designed as a drop-in replacement for localStorage with durability and performance.
|
|
4
|
-
*
|
|
5
|
-
* @author Jelodar
|
|
6
|
-
* @license MIT
|
|
7
|
-
*/
|
|
1
|
+
/** tiny-idb - MIT © Jelodar */
|
|
8
2
|
|
|
9
3
|
const instances = new Map();
|
|
10
4
|
const prom = (req) => new Promise((res, rej) => {
|
|
@@ -43,23 +37,24 @@ const getAPI = (dbName = 'tiny-idb', storeName = undefined) => {
|
|
|
43
37
|
});
|
|
44
38
|
};
|
|
45
39
|
|
|
46
|
-
const update =
|
|
47
|
-
const n = await fn(await prom(s.get(key)));
|
|
48
|
-
return prom(s.put(n, key));
|
|
49
|
-
});
|
|
40
|
+
const update = (key, fn) => tx(RW, async s => prom(s.put(await fn(await prom(s.get(key))), key)));
|
|
50
41
|
|
|
51
42
|
const api = {
|
|
52
43
|
open: getAPI,
|
|
53
44
|
set: (key, value) => tx(RW, s => prom(s.put(value, key))),
|
|
54
45
|
get: key => tx(RO, s => prom(s.get(key))),
|
|
55
|
-
remove:
|
|
46
|
+
remove: key => tx(RW, s => prom(s.delete(key))),
|
|
56
47
|
clear: () => tx(RW, s => prom(s.clear())),
|
|
57
48
|
keys: () => tx(RO, s => prom(s.getAllKeys())),
|
|
58
49
|
values: () => tx(RO, s => prom(s.getAll())),
|
|
50
|
+
entries: () => tx(RO, async s => {
|
|
51
|
+
const [k, v] = await Promise.all([prom(s.getAllKeys()), prom(s.getAll())]);
|
|
52
|
+
return k.map((key, i) => [key, v[i]]);
|
|
53
|
+
}),
|
|
59
54
|
count: () => tx(RO, s => prom(s.count())),
|
|
60
55
|
update,
|
|
61
|
-
push: (key,
|
|
62
|
-
merge: (key,
|
|
56
|
+
push: (key, val) => update(key, (c = []) => [...(Array.isArray(c) ? c : []), val]),
|
|
57
|
+
merge: (key, obj) => update(key, (c = {}) => ({ ...(c && typeof c === 'object' ? c : {}), ...obj }))
|
|
63
58
|
};
|
|
64
59
|
|
|
65
60
|
['get', 'set', 'remove'].forEach(m => api[m + 'Item'] = api[m]);
|
package/tiny-idb.min.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
/** tiny-idb - MIT © Jelodar */
|
|
2
|
+
const e=new Map,t=e=>new Promise((t,r)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>r(e.error)}),r="readonly",o="readwrite",n=(s="tiny-idb",a=void 0)=>{const c=s+"\0"+(a=a||s);if(e.has(c))return e.get(c);let l;const i=async(e,t)=>{const r=await(l||(l=new Promise((e,t)=>{const r=indexedDB.open(s,1);r.onupgradeneeded=()=>r.result.createObjectStore(a),r.onsuccess=()=>{const t=r.result;t.onversionchange=()=>{t.close(),l=null},e(t)},r.onerror=()=>{l=null,t(r.error)}})));return new Promise(async(o,n)=>{const s=r.transaction(a,e);s.onabort=s.onerror=()=>n(s.error||new DOMException("Aborted"));try{const e=await t(s.objectStore(a));s.oncomplete=()=>o(e)}catch(e){try{s.abort()}catch{}n(e)}})},u=(e,r)=>i(o,async o=>t(o.put(await r(await t(o.get(e))),e))),y={open:n,set:(e,r)=>i(o,o=>t(o.put(r,e))),get:e=>i(r,r=>t(r.get(e))),remove:e=>i(o,r=>t(r.delete(e))),clear:()=>i(o,e=>t(e.clear())),keys:()=>i(r,e=>t(e.getAllKeys())),values:()=>i(r,e=>t(e.getAll())),entries:()=>i(r,async e=>{const[r,o]=await Promise.all([t(e.getAllKeys()),t(e.getAll())]);return r.map((e,t)=>[e,o[t]])}),count:()=>i(r,e=>t(e.count())),update:u,push:(e,t)=>u(e,(e=[])=>[...Array.isArray(e)?e:[],t]),merge:(e,t)=>u(e,(e={})=>({...e&&"object"==typeof e?e:{},...t}))};return["get","set","remove"].forEach(e=>y[e+"Item"]=y[e]),e.set(c,y),y};export const tinyIDB=n();export default tinyIDB;
|