forked from Expensify/react-native-onyx
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8968165
commit 85081c1
Showing
1 changed file
with
84 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,108 @@ | ||
// TODO: Fix types | ||
import Dexie from 'dexie'; | ||
import type {EntityTable} from 'dexie'; | ||
import utils from '../../utils'; | ||
import type StorageProvider from './types'; | ||
import type {OnyxKey, OnyxValue} from '../../types'; | ||
|
||
type DexieDatabase = Dexie & { | ||
keyvaluepairs: EntityTable<OnyxValue<OnyxKey>, OnyxKey>; // TODO typings | ||
}; | ||
class OnyxDatabase extends Dexie { | ||
keyvaluepairs!: Dexie.Table<OnyxValue<OnyxKey>, OnyxKey>; | ||
|
||
constructor() { | ||
super('OnyxDB'); | ||
this.version(0.1).stores({ | ||
keyvaluepairs: '', | ||
}); | ||
} | ||
} | ||
|
||
let db: DexieDatabase; | ||
let db: OnyxDatabase; | ||
|
||
const initDB = () => { | ||
if (!db) { | ||
db = new OnyxDatabase(); | ||
return db.open(); | ||
} | ||
return Promise.resolve(); | ||
}; | ||
|
||
const provider: StorageProvider = { | ||
/** | ||
* The name of the provider that can be printed to the logs | ||
*/ | ||
name: 'DexieProvider', | ||
/** | ||
* Initializes the storage provider | ||
*/ | ||
init() { | ||
db = new Dexie('OnyxDB') as DexieDatabase; | ||
}, | ||
init: initDB, | ||
|
||
setItem: (key, value) => { | ||
Check failure on line 35 in lib/storage/providers/DexieProvider.ts GitHub Actions / lint
|
||
if (value === null) { | ||
provider.removeItem(key); | ||
return provider.removeItem(key); | ||
} | ||
|
||
return db.keyvaluepairs.put(value, key); | ||
}, | ||
// multiGet: (keys) => db.keyvaluepairs.bulkGet(keys), | ||
// multiMerge: (pairs) => db.keyvaluepairs.bulkPut(items, keys, options), | ||
mergeItem(key, _deltaChanges, preMergedValue) { | ||
multiGet: (keysParam) => { | ||
return db.keyvaluepairs.bulkGet(keysParam).then((results) => { | ||
return results.map((result, index) => [keysParam[index], result ?? null]); | ||
}); | ||
}, | ||
multiMerge: (pairs) => { | ||
Check failure on line 46 in lib/storage/providers/DexieProvider.ts GitHub Actions / lint
|
||
return db.transaction('rw', db.keyvaluepairs, () => { | ||
return Promise.all( | ||
pairs.map(([key, value]) => { | ||
if (value === null) { | ||
return provider.removeItem(key); | ||
} | ||
return db.keyvaluepairs.get(key).then((existingItem) => { | ||
const newValue = utils.fastMerge(existingItem as Record<string, unknown>, value as Record<string, unknown>); | ||
return db.keyvaluepairs.put(newValue, key); | ||
}); | ||
}), | ||
); | ||
}); | ||
}, | ||
mergeItem: (key, _deltaChanges, preMergedValue) => { | ||
// Since Onyx also merged the existing value with the changes, we can just set the value directly | ||
return provider.setItem(key, preMergedValue); | ||
}, | ||
// multiSet: (pairs) => {}, | ||
clear: () => db.keyvaluepairs.clear(), | ||
getAllKeys: () => db.keyvaluepairs.toCollection().keys(), | ||
getItem: (key) => db.keyvaluepairs.get(key), | ||
removeItem: (key) => db.keyvaluepairs.delete(key), | ||
removeItems: (keys) => db.keyvaluepairs.bulkDelete(keys), | ||
getDatabaseSize() { | ||
return Promise.resolve({ | ||
bytesUsed: 0, | ||
bytesRemaining: 0, | ||
multiSet: (pairs) => { | ||
const pairsWithoutNull = pairs.filter(([, value]) => value !== null); | ||
return db.keyvaluepairs.bulkPut( | ||
pairsWithoutNull.map(([, value]) => value), | ||
pairsWithoutNull.map(([key]) => key), | ||
); | ||
}, | ||
clear: () => { | ||
return db.keyvaluepairs.clear(); | ||
}, | ||
getAllKeys: () => { | ||
return db.keyvaluepairs.toCollection().keys(); | ||
}, | ||
getItem: (key) => { | ||
Check failure on line 78 in lib/storage/providers/DexieProvider.ts GitHub Actions / lint
|
||
return db.keyvaluepairs.get(key).then((result) => { | ||
return result ?? null; | ||
}); | ||
}, | ||
removeItem: (key) => { | ||
return db.keyvaluepairs.delete(key); | ||
}, | ||
removeItems: (keysParam) => { | ||
return db.keyvaluepairs.bulkDelete(keysParam); | ||
}, | ||
getDatabaseSize: () => { | ||
if (!window.navigator || !window.navigator.storage) { | ||
return Promise.reject(new Error('StorageManager browser API unavailable')); | ||
} | ||
|
||
return window.navigator.storage | ||
.estimate() | ||
.then((estimate) => { | ||
return { | ||
bytesUsed: estimate.usage ?? 0, | ||
bytesRemaining: (estimate.quota ?? 0) - (estimate.usage ?? 0), | ||
}; | ||
}) | ||
.catch((error) => { | ||
throw new Error(`Unable to estimate web storage quota. Original error: ${error}`); | ||
}); | ||
}, | ||
}; | ||
|
||
export default provider; |