A small wrapper that makes IndexedDB usable with promises and enhanced TypeScript support
npx @tessl/cli install tessl/npm-idb@8.0.00
# IDB
1
2
IDB is a lightweight TypeScript wrapper around the browser's IndexedDB API that significantly improves usability while maintaining the core functionality. It transforms callback-based IDBRequest objects into promises, adds convenient shortcut methods for common database operations, provides enhanced transaction handling with automatic lifetime management, and includes TypeScript support with strongly-typed database schemas.
3
4
## Package Information
5
6
- **Package Name**: idb
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install idb`
10
11
## Core Imports
12
13
```typescript
14
import { openDB, deleteDB, wrap, unwrap } from "idb";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { openDB, deleteDB, wrap, unwrap } = require("idb");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { openDB } from "idb";
27
28
// Define database schema
29
interface MyDB {
30
people: {
31
key: number;
32
value: {
33
name: string;
34
age: number;
35
};
36
indexes: { name: string };
37
};
38
}
39
40
// Open database with schema
41
const db = await openDB<MyDB>("my-database", 1, {
42
upgrade(db) {
43
const peopleStore = db.createObjectStore("people", {
44
keyPath: "id",
45
autoIncrement: true,
46
});
47
peopleStore.createIndex("name", "name");
48
},
49
});
50
51
// Use database with shortcut methods
52
await db.add("people", { name: "Alice", age: 30 });
53
const person = await db.get("people", 1);
54
const allPeople = await db.getAll("people");
55
56
// Iterate over all records using async iteration
57
const tx = db.transaction("people");
58
for await (const cursor of tx.store) {
59
console.log(cursor.key, cursor.value);
60
}
61
```
62
63
## Architecture
64
65
IDB is built around several key components:
66
67
- **Database Management**: `openDB` and `deleteDB` functions for database lifecycle management
68
- **Promise Wrapping**: Core `wrap`/`unwrap` system converting IDB objects to promise-based equivalents
69
- **Enhanced Interfaces**: TypeScript interfaces (`IDBPDatabase`, `IDBPTransaction`, etc.) with promise-based methods
70
- **Shortcut Methods**: Direct database operations without explicit transaction management
71
- **Async Iteration**: Support for `for await` loops over cursors, stores, and indexes
72
- **Type Safety**: Full TypeScript integration with strongly-typed database schemas
73
74
## Capabilities
75
76
### Database Operations
77
78
Core database lifecycle management including opening databases with upgrade callbacks, deleting databases, and handling database events.
79
80
```typescript { .api }
81
function openDB<DBTypes extends DBSchema | unknown = unknown>(
82
name: string,
83
version?: number,
84
{ blocked, upgrade, blocking, terminated }: OpenDBCallbacks<DBTypes> = {}
85
): Promise<IDBPDatabase<DBTypes>>;
86
87
function deleteDB(
88
name: string,
89
{ blocked }: DeleteDBCallbacks = {}
90
): Promise<void>;
91
```
92
93
[Database Operations](./database-operations.md)
94
95
### Promise Wrapping
96
97
Low-level utilities for converting native IndexedDB objects to promise-based equivalents and vice versa.
98
99
```typescript { .api }
100
function wrap(value: IDBDatabase): IDBPDatabase;
101
function wrap(value: IDBRequest<T>): Promise<T>;
102
103
function unwrap(value: IDBPDatabase): IDBDatabase;
104
function unwrap<T>(value: Promise<T>): IDBRequest<T>;
105
106
function replaceTraps(
107
callback: (currentTraps: ProxyHandler<any>) => ProxyHandler<any>
108
): void;
109
```
110
111
[Promise Wrapping](./promise-wrapping.md)
112
113
### Enhanced Database Interface
114
115
Promise-based database interface with shortcut methods for common operations, eliminating the need for explicit transaction management in simple cases.
116
117
```typescript { .api }
118
interface IDBPDatabase<DBTypes extends DBSchema | unknown = unknown> {
119
// Transaction methods
120
transaction<Name extends StoreNames<DBTypes>, Mode extends IDBTransactionMode = 'readonly'>(
121
storeNames: Name,
122
mode?: Mode,
123
options?: IDBTransactionOptions
124
): IDBPTransaction<DBTypes, [Name], Mode>;
125
126
// Shortcut methods
127
add<Name extends StoreNames<DBTypes>>(
128
storeName: Name,
129
value: StoreValue<DBTypes, Name>,
130
key?: StoreKey<DBTypes, Name> | IDBKeyRange
131
): Promise<StoreKey<DBTypes, Name>>;
132
133
get<Name extends StoreNames<DBTypes>>(
134
storeName: Name,
135
query: StoreKey<DBTypes, Name> | IDBKeyRange
136
): Promise<StoreValue<DBTypes, Name> | undefined>;
137
138
put<Name extends StoreNames<DBTypes>>(
139
storeName: Name,
140
value: StoreValue<DBTypes, Name>,
141
key?: StoreKey<DBTypes, Name> | IDBKeyRange
142
): Promise<StoreKey<DBTypes, Name>>;
143
}
144
```
145
146
[Enhanced Database Interface](./enhanced-database.md)
147
148
### Transaction Management
149
150
Enhanced transaction interface with automatic completion handling and convenient store access.
151
152
```typescript { .api }
153
interface IDBPTransaction<
154
DBTypes extends DBSchema | unknown = unknown,
155
TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>,
156
Mode extends IDBTransactionMode = 'readonly'
157
> {
158
readonly mode: Mode;
159
readonly objectStoreNames: TypedDOMStringList<TxStores[number]>;
160
readonly db: IDBPDatabase<DBTypes>;
161
readonly done: Promise<void>;
162
readonly store: TxStores[1] extends undefined
163
? IDBPObjectStore<DBTypes, TxStores, TxStores[0], Mode>
164
: undefined;
165
166
objectStore<StoreName extends TxStores[number]>(
167
name: StoreName
168
): IDBPObjectStore<DBTypes, TxStores, StoreName, Mode>;
169
}
170
```
171
172
[Transaction Management](./transaction-management.md)
173
174
### Object Store Operations
175
176
Enhanced object store interface with promise-based operations and async iteration support.
177
178
```typescript { .api }
179
interface IDBPObjectStore<
180
DBTypes extends DBSchema | unknown = unknown,
181
TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>,
182
StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>,
183
Mode extends IDBTransactionMode = 'readonly'
184
> {
185
// Core operations
186
add: Mode extends 'readonly' ? undefined : (
187
value: StoreValue<DBTypes, StoreName>,
188
key?: StoreKey<DBTypes, StoreName> | IDBKeyRange
189
) => Promise<StoreKey<DBTypes, StoreName>>;
190
191
get(
192
query: StoreKey<DBTypes, StoreName> | IDBKeyRange
193
): Promise<StoreValue<DBTypes, StoreName> | undefined>;
194
195
// Iteration support
196
[Symbol.asyncIterator](): AsyncIterableIterator<
197
IDBPCursorWithValueIteratorValue<DBTypes, TxStores, StoreName, unknown, Mode>
198
>;
199
}
200
```
201
202
[Object Store Operations](./object-store-operations.md)
203
204
### Index Operations
205
206
Enhanced index interface for querying data by secondary keys with full async iteration support.
207
208
```typescript { .api }
209
interface IDBPIndex<
210
DBTypes extends DBSchema | unknown = unknown,
211
TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>,
212
StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>,
213
IndexName extends IndexNames<DBTypes, StoreName> = IndexNames<DBTypes, StoreName>,
214
Mode extends IDBTransactionMode = 'readonly'
215
> {
216
readonly objectStore: IDBPObjectStore<DBTypes, TxStores, StoreName, Mode>;
217
218
get(
219
query: IndexKey<DBTypes, StoreName, IndexName> | IDBKeyRange
220
): Promise<StoreValue<DBTypes, StoreName> | undefined>;
221
222
openCursor(
223
query?: IndexKey<DBTypes, StoreName, IndexName> | IDBKeyRange | null,
224
direction?: IDBCursorDirection
225
): Promise<IDBPCursorWithValue<DBTypes, TxStores, StoreName, IndexName, Mode> | null>;
226
}
227
```
228
229
[Index Operations](./index-operations.md)
230
231
### Cursor Navigation
232
233
Enhanced cursor interfaces with promise-based navigation and async iteration support for efficient data traversal.
234
235
```typescript { .api }
236
interface IDBPCursor<
237
DBTypes extends DBSchema | unknown = unknown,
238
TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>,
239
StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>,
240
IndexName extends IndexNames<DBTypes, StoreName> | unknown = unknown,
241
Mode extends IDBTransactionMode = 'readonly'
242
> {
243
readonly key: IndexName extends IndexNames<DBTypes, StoreName>
244
? IndexKey<DBTypes, StoreName, IndexName>
245
: StoreKey<DBTypes, StoreName>;
246
readonly primaryKey: StoreKey<DBTypes, StoreName>;
247
248
advance<T>(this: T, count: number): Promise<T | null>;
249
continue<T>(this: T, key?: IndexName extends IndexNames<DBTypes, StoreName>
250
? IndexKey<DBTypes, StoreName, IndexName>
251
: StoreKey<DBTypes, StoreName>): Promise<T | null>;
252
253
[Symbol.asyncIterator](): AsyncIterableIterator<
254
IDBPCursorIteratorValue<DBTypes, TxStores, StoreName, IndexName, Mode>
255
>;
256
}
257
258
interface IDBPCursorWithValue<...> extends IDBPCursor<...> {
259
readonly value: StoreValue<DBTypes, StoreName>;
260
}
261
```
262
263
[Cursor Navigation](./cursor-navigation.md)
264
265
## Types
266
267
```typescript { .api }
268
interface DBSchema {
269
[s: string]: DBSchemaValue;
270
}
271
272
interface DBSchemaValue {
273
key: IDBValidKey;
274
value: any;
275
indexes?: IndexKeys;
276
}
277
278
interface IndexKeys {
279
[s: string]: IDBValidKey;
280
}
281
282
interface OpenDBCallbacks<DBTypes extends DBSchema | unknown> {
283
upgrade?(
284
database: IDBPDatabase<DBTypes>,
285
oldVersion: number,
286
newVersion: number | null,
287
transaction: IDBPTransaction<DBTypes, StoreNames<DBTypes>[], 'versionchange'>,
288
event: IDBVersionChangeEvent
289
): void;
290
blocked?(currentVersion: number, blockedVersion: number | null, event: IDBVersionChangeEvent): void;
291
blocking?(currentVersion: number, blockedVersion: number | null, event: IDBVersionChangeEvent): void;
292
terminated?(): void;
293
}
294
295
interface DeleteDBCallbacks {
296
blocked?(currentVersion: number, event: IDBVersionChangeEvent): void;
297
}
298
299
type StoreNames<DBTypes extends DBSchema | unknown> =
300
DBTypes extends DBSchema ? KnownKeys<DBTypes> : string;
301
302
type StoreValue<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> =
303
DBTypes extends DBSchema ? DBTypes[StoreName]['value'] : any;
304
305
type StoreKey<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> =
306
DBTypes extends DBSchema ? DBTypes[StoreName]['key'] : IDBValidKey;
307
308
type IndexNames<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> =
309
DBTypes extends DBSchema ? keyof DBTypes[StoreName]['indexes'] & string : string;
310
311
type IndexKey<
312
DBTypes extends DBSchema | unknown,
313
StoreName extends StoreNames<DBTypes>,
314
IndexName extends IndexNames<DBTypes, StoreName>
315
> = DBTypes extends DBSchema
316
? IndexName extends keyof DBTypes[StoreName]['indexes']
317
? DBTypes[StoreName]['indexes'][IndexName]
318
: IDBValidKey
319
: IDBValidKey;
320
321
interface TypedDOMStringList<T extends string> extends DOMStringList {
322
contains(string: T): boolean;
323
item(index: number): T | null;
324
[index: number]: T;
325
[Symbol.iterator](): IterableIterator<T>;
326
}
327
328
interface IDBTransactionOptions {
329
durability?: 'default' | 'strict' | 'relaxed';
330
}
331
```