0
# Driver Development
1
2
Advanced functionality for defining custom storage drivers and inspecting driver capabilities. This enables extending localForage with custom storage backends and provides tools for understanding the current storage environment.
3
4
## Capabilities
5
6
### Define Custom Driver
7
8
Registers a custom storage driver that implements the localForage storage interface. Custom drivers allow integration with specialized storage systems or services.
9
10
```javascript { .api }
11
/**
12
* Defines a custom storage driver
13
* @param driver - Driver implementation object
14
* @param callback - Optional success callback
15
* @param errorCallback - Optional error callback
16
* @returns Promise resolving when driver is defined
17
*/
18
function defineDriver(
19
driver: LocalForageDriver,
20
callback?: () => void,
21
errorCallback?: (error: any) => void
22
): Promise<void>;
23
```
24
25
**Usage Examples:**
26
27
```javascript
28
import localforage from 'localforage';
29
30
// Define a simple in-memory storage driver
31
const memoryDriver = {
32
_driver: 'memoryStorageDriver',
33
_initStorage: function(options) {
34
const dbInfo = {};
35
dbInfo.db = {};
36
this._dbInfo = dbInfo;
37
},
38
_support: true,
39
40
async getItem(key) {
41
return this._dbInfo.db[key] || null;
42
},
43
44
async setItem(key, value) {
45
this._dbInfo.db[key] = value;
46
return value;
47
},
48
49
async removeItem(key) {
50
delete this._dbInfo.db[key];
51
},
52
53
async clear() {
54
this._dbInfo.db = {};
55
},
56
57
async length() {
58
return Object.keys(this._dbInfo.db).length;
59
},
60
61
async key(n) {
62
const keys = Object.keys(this._dbInfo.db);
63
return keys[n] || null;
64
},
65
66
async keys() {
67
return Object.keys(this._dbInfo.db);
68
},
69
70
async iterate(iteratee) {
71
const keys = Object.keys(this._dbInfo.db);
72
for (let i = 0; i < keys.length; i++) {
73
const key = keys[i];
74
const value = this._dbInfo.db[key];
75
const result = iteratee(value, key, i);
76
if (result !== undefined) {
77
return result;
78
}
79
}
80
}
81
};
82
83
// Register the custom driver
84
await localforage.defineDriver(memoryDriver);
85
86
// Use the custom driver
87
await localforage.setDriver('memoryStorageDriver');
88
89
// Define a driver with async support detection
90
const customAsyncDriver = {
91
_driver: 'customAsyncStorageDriver',
92
_support: async function() {
93
// Check if the storage backend is available
94
return typeof customStorageAPI !== 'undefined';
95
},
96
// ... implement other required methods
97
};
98
99
await localforage.defineDriver(customAsyncDriver);
100
```
101
102
### Get Current Driver Name
103
104
Returns the name of the currently active storage driver.
105
106
```javascript { .api }
107
/**
108
* Gets the name of the current storage driver
109
* @returns The current driver name
110
*/
111
function driver(): string;
112
```
113
114
**Usage Examples:**
115
116
```javascript
117
import localforage from 'localforage';
118
119
// Check which driver is currently being used
120
const currentDriver = localforage.driver();
121
console.log('Current driver:', currentDriver);
122
// Output might be: 'asyncStorage' (IndexedDB), 'webSQLStorage', or 'localStorageWrapper'
123
124
// Conditional logic based on current driver
125
const driverName = localforage.driver();
126
if (driverName === localforage.INDEXEDDB) {
127
console.log('Using IndexedDB - optimal for large data');
128
} else if (driverName === localforage.LOCALSTORAGE) {
129
console.log('Using localStorage - limited storage capacity');
130
}
131
132
// Store driver information for debugging
133
const debugInfo = {
134
driver: localforage.driver(),
135
timestamp: new Date().toISOString(),
136
config: localforage.config()
137
};
138
```
139
140
### Get Driver Implementation
141
142
Retrieves the implementation object for a specific driver by name.
143
144
```javascript { .api }
145
/**
146
* Gets the implementation of a specific driver
147
* @param driver - Name of the driver to retrieve
148
* @returns Promise resolving to the driver implementation
149
*/
150
function getDriver(driver: string): Promise<LocalForageDriver>;
151
```
152
153
**Usage Examples:**
154
155
```javascript
156
import localforage from 'localforage';
157
158
// Get IndexedDB driver implementation
159
const idbDriver = await localforage.getDriver(localforage.INDEXEDDB);
160
console.log('IndexedDB driver:', idbDriver);
161
162
// Inspect driver capabilities
163
const currentDriverName = localforage.driver();
164
const driverImpl = await localforage.getDriver(currentDriverName);
165
console.log('Current driver methods:', Object.keys(driverImpl));
166
167
// Check if driver supports optional methods
168
const driver = await localforage.getDriver(localforage.INDEXEDDB);
169
if (typeof driver.dropInstance === 'function') {
170
console.log('Driver supports dropInstance method');
171
}
172
173
// Get custom driver implementation
174
await localforage.defineDriver(myCustomDriver);
175
const customDriver = await localforage.getDriver('myCustomDriverName');
176
```
177
178
### Check Driver Support
179
180
Tests whether a specific driver is supported in the current environment.
181
182
```javascript { .api }
183
/**
184
* Checks if a driver is supported in the current environment
185
* @param driverName - Name of the driver to check
186
* @returns Boolean indicating if the driver is supported
187
*/
188
function supports(driverName: string): boolean;
189
```
190
191
**Usage Examples:**
192
193
```javascript
194
import localforage from 'localforage';
195
196
// Check support for specific drivers
197
const supportsIndexedDB = localforage.supports(localforage.INDEXEDDB);
198
const supportsWebSQL = localforage.supports(localforage.WEBSQL);
199
const supportsLocalStorage = localforage.supports(localforage.LOCALSTORAGE);
200
201
console.log('Driver support:');
202
console.log('- IndexedDB:', supportsIndexedDB);
203
console.log('- WebSQL:', supportsWebSQL);
204
console.log('- localStorage:', supportsLocalStorage);
205
206
// Build optimal driver list based on support
207
const supportedDrivers = [];
208
if (localforage.supports(localforage.INDEXEDDB)) {
209
supportedDrivers.push(localforage.INDEXEDDB);
210
}
211
if (localforage.supports(localforage.WEBSQL)) {
212
supportedDrivers.push(localforage.WEBSQL);
213
}
214
if (localforage.supports(localforage.LOCALSTORAGE)) {
215
supportedDrivers.push(localforage.LOCALSTORAGE);
216
}
217
218
await localforage.setDriver(supportedDrivers);
219
220
// Check custom driver support
221
const supportsCustom = localforage.supports('myCustomDriver');
222
if (!supportsCustom) {
223
console.warn('Custom driver not supported, falling back to defaults');
224
}
225
```
226
227
### Wait for Ready State
228
229
Waits for localForage to be fully initialized and ready for operations.
230
231
```javascript { .api }
232
/**
233
* Waits for localForage to be ready
234
* @param callback - Optional callback function
235
* @returns Promise resolving when localForage is ready
236
*/
237
function ready(callback?: (error: any) => void): Promise<void>;
238
```
239
240
**Usage Examples:**
241
242
```javascript
243
import localforage from 'localforage';
244
245
// Wait for localForage to be ready before operations
246
await localforage.ready();
247
console.log('localForage is ready');
248
249
// Now safe to perform storage operations
250
await localforage.setItem('key', 'value');
251
252
// Using callbacks
253
localforage.ready((error) => {
254
if (error) {
255
console.error('localForage failed to initialize:', error);
256
} else {
257
console.log('localForage is ready');
258
// Perform initial storage operations
259
}
260
});
261
262
// Combine with driver setup
263
localforage.config({
264
driver: localforage.INDEXEDDB,
265
name: 'MyApp'
266
});
267
268
await localforage.ready();
269
console.log('Configured with driver:', localforage.driver());
270
```
271
272
### Get Serializer
273
274
Retrieves the current serializer used for data conversion between JavaScript types and storage formats.
275
276
```javascript { .api }
277
/**
278
* Gets the current serializer instance
279
* @param callback - Optional callback function
280
* @returns Promise resolving to the serializer object
281
*/
282
function getSerializer(callback?: (serializer: LocalForageSerializer) => void): Promise<LocalForageSerializer>;
283
```
284
285
**Usage Examples:**
286
287
```javascript
288
import localforage from 'localforage';
289
290
// Get the current serializer
291
const serializer = await localforage.getSerializer();
292
console.log('Serializer methods:', Object.keys(serializer));
293
294
// Use serializer directly for custom operations
295
const serializer = await localforage.getSerializer();
296
const data = { key: 'value', array: [1, 2, 3] };
297
298
serializer.serialize(data, (serializedData, error) => {
299
if (error) {
300
console.error('Serialization error:', error);
301
} else {
302
console.log('Serialized data:', serializedData);
303
304
// Deserialize back
305
const originalData = serializer.deserialize(serializedData);
306
console.log('Deserialized data:', originalData);
307
}
308
});
309
```
310
311
## Driver Interface
312
313
```javascript { .api }
314
interface LocalForageDriver {
315
/**
316
* Unique identifier for the driver
317
*/
318
_driver: string;
319
320
/**
321
* Initialize storage with given options
322
*/
323
_initStorage(options: LocalForageOptions): void;
324
325
/**
326
* Support check - boolean or async function
327
*/
328
_support?: boolean | (() => Promise<boolean>);
329
330
// Required storage methods
331
getItem<T>(key: string, callback?: (err: any, value: T | null) => void): Promise<T | null>;
332
setItem<T>(key: string, value: T, callback?: (err: any, value: T) => void): Promise<T>;
333
removeItem(key: string, callback?: (err: any) => void): Promise<void>;
334
clear(callback?: (err: any) => void): Promise<void>;
335
length(callback?: (err: any, numberOfKeys: number) => void): Promise<number>;
336
key(keyIndex: number, callback?: (err: any, key: string) => void): Promise<string>;
337
keys(callback?: (err: any, keys: string[]) => void): Promise<string[]>;
338
iterate<T, U>(
339
iteratee: (value: T, key: string, iterationNumber: number) => U,
340
callback?: (err: any, result: U) => void
341
): Promise<U>;
342
343
// Optional methods
344
dropInstance?(dbInstanceOptions?: LocalForageDbInstanceOptions, callback?: (err: any) => void): Promise<void>;
345
}
346
347
interface LocalForageSerializer {
348
/**
349
* Serialize a value for storage
350
*/
351
serialize<T>(value: T | ArrayBuffer | Blob, callback: (value: string, error: any) => void): void;
352
353
/**
354
* Deserialize a stored value
355
*/
356
deserialize<T>(value: string): T | ArrayBuffer | Blob;
357
358
/**
359
* Convert string to ArrayBuffer
360
*/
361
stringToBuffer(serializedString: string): ArrayBuffer;
362
363
/**
364
* Convert ArrayBuffer to string
365
*/
366
bufferToString(buffer: ArrayBuffer): string;
367
}
368
```
369
370
## Advanced Driver Development
371
372
### Custom Driver Template
373
374
```javascript
375
// Template for creating a custom driver
376
const customDriverTemplate = {
377
// Required: Unique driver identifier
378
_driver: 'customStorageDriver',
379
380
// Required: Initialization function
381
_initStorage: function(options) {
382
// Initialize storage backend
383
// Store configuration in this._dbInfo
384
const dbInfo = {
385
db: null, // Your storage backend connection
386
name: options.name,
387
storeName: options.storeName
388
};
389
this._dbInfo = dbInfo;
390
391
// Perform any async initialization if needed
392
return new Promise((resolve, reject) => {
393
// Initialize your storage backend
394
// resolve() when ready, reject(error) on failure
395
resolve();
396
});
397
},
398
399
// Optional: Support detection
400
_support: function() {
401
// Return boolean or Promise<boolean>
402
return typeof YourStorageAPI !== 'undefined';
403
},
404
405
// Required: Implement all storage methods
406
async getItem(key, callback) {
407
try {
408
const value = await this._dbInfo.db.get(key);
409
if (callback) callback(null, value);
410
return value;
411
} catch (error) {
412
if (callback) callback(error);
413
throw error;
414
}
415
},
416
417
async setItem(key, value, callback) {
418
try {
419
await this._dbInfo.db.set(key, value);
420
if (callback) callback(null, value);
421
return value;
422
} catch (error) {
423
if (callback) callback(error);
424
throw error;
425
}
426
}
427
428
// ... implement other required methods
429
};
430
```
431
432
### Driver Registration and Usage
433
434
```javascript
435
// Register and use a custom driver
436
async function setupCustomStorage() {
437
// Define the driver
438
await localforage.defineDriver(customDriverTemplate);
439
440
// Check if it's supported
441
if (localforage.supports('customStorageDriver')) {
442
// Set as primary driver
443
await localforage.setDriver('customStorageDriver');
444
console.log('Custom driver is active');
445
} else {
446
console.warn('Custom driver not supported, using fallback');
447
await localforage.setDriver([
448
localforage.INDEXEDDB,
449
localforage.LOCALSTORAGE
450
]);
451
}
452
453
// Wait for initialization
454
await localforage.ready();
455
456
// Now ready to use
457
await localforage.setItem('test', 'Custom driver works!');
458
}
459
460
setupCustomStorage();
461
```
462
463
## Built-in Driver Constants
464
465
```javascript
466
// Driver identifiers available as constants
467
localforage.INDEXEDDB // 'asyncStorage'
468
localforage.WEBSQL // 'webSQLStorage'
469
localforage.LOCALSTORAGE // 'localStorageWrapper'
470
471
// Usage in driver selection
472
await localforage.setDriver([
473
localforage.INDEXEDDB, // Primary choice
474
localforage.WEBSQL, // Secondary fallback
475
localforage.LOCALSTORAGE // Final fallback
476
]);
477
```