-
Notifications
You must be signed in to change notification settings - Fork 86
/
db.ts
110 lines (100 loc) · 3.32 KB
/
db.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { openDB, IDBPDatabase } from 'idb';
import { KEY_STORAGE_DELEGATION, KEY_STORAGE_KEY } from './storage';
type Database = IDBPDatabase<unknown>;
type IDBValidKey = string | number | Date | BufferSource | IDBValidKey[];
const AUTH_DB_NAME = 'auth-client-db';
const OBJECT_STORE_NAME = 'ic-keyval';
const _openDbStore = async (
dbName = AUTH_DB_NAME,
storeName = OBJECT_STORE_NAME,
version: number,
) => {
// Clear legacy stored delegations
if (localStorage && localStorage.getItem(KEY_STORAGE_DELEGATION)) {
localStorage.removeItem(KEY_STORAGE_DELEGATION);
localStorage.removeItem(KEY_STORAGE_KEY);
}
return await openDB(dbName, version, {
upgrade: database => {
database.objectStoreNames;
if (database.objectStoreNames.contains(storeName)) {
database.clear(storeName);
}
database.createObjectStore(storeName);
},
});
};
async function _getValue<T>(
db: Database,
storeName: string,
key: IDBValidKey,
): Promise<T | undefined> {
return await db.get(storeName, key);
}
async function _setValue<T>(
db: Database,
storeName: string,
key: IDBValidKey,
value: T,
): Promise<IDBValidKey> {
return await db.put(storeName, value, key);
}
async function _removeValue(db: Database, storeName: string, key: IDBValidKey): Promise<void> {
return await db.delete(storeName, key);
}
export type DBCreateOptions = {
dbName?: string;
storeName?: string;
version?: number;
};
/**
* Simple Key Value store
* Defaults to `'auth-client-db'` with an object store of `'ic-keyval'`
*/
export class IdbKeyVal {
/**
*
* @param {DBCreateOptions} options {@link DbCreateOptions}
* @param {DBCreateOptions['dbName']} options.dbName name for the indexeddb database
* @default 'auth-client-db'
* @param {DBCreateOptions['storeName']} options.storeName name for the indexeddb Data Store
* @default 'ic-keyval'
* @param {DBCreateOptions['version']} options.version version of the database. Increment to safely upgrade
* @constructs an {@link IdbKeyVal}
*/
public static async create(options?: DBCreateOptions): Promise<IdbKeyVal> {
const { dbName = AUTH_DB_NAME, storeName = OBJECT_STORE_NAME, version = 1 } = options ?? {};
const db = await _openDbStore(dbName, storeName, version);
return new IdbKeyVal(db, storeName);
}
// Do not use - instead prefer create
private constructor(private _db: Database, private _storeName: string) {}
/**
* Basic setter
* @param {IDBValidKey} key string | number | Date | BufferSource | IDBValidKey[]
* @param value value to set
* @returns void
*/
public async set<T>(key: IDBValidKey, value: T) {
return await _setValue<T>(this._db, this._storeName, key, value);
}
/**
* Basic getter
* Pass in a type T for type safety if you know the type the value will have if it is found
* @param {IDBValidKey} key string | number | Date | BufferSource | IDBValidKey[]
* @returns `Promise<T | null>`
* @example
* await get<string>('exampleKey') -> 'exampleValue'
*/
public async get<T>(key: IDBValidKey): Promise<T | null> {
return (await _getValue<T>(this._db, this._storeName, key)) ?? null;
}
/**
* Remove a key
* @param key {@link IDBValidKey}
* @returns void
*/
public async remove(key: IDBValidKey) {
return await _removeValue(this._db, this._storeName, key);
}
}