Skip to content

Commit

Permalink
full Dexie provider implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
TMisiukiewicz committed Aug 30, 2024
1 parent 8968165 commit 85081c1
Showing 1 changed file with 84 additions and 26 deletions.
110 changes: 84 additions & 26 deletions lib/storage/providers/DexieProvider.ts
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

View workflow job for this annotation

GitHub Actions / lint

Type '<TKey extends string>(key: TKey, value: OnyxValue<TKey>) => Promise<void | QueryResult> | PromiseExtended<string>' is not assignable to type '<TKey extends string>(key: TKey, value: OnyxValue<TKey>) => Promise<void | QueryResult>'.
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

View workflow job for this annotation

GitHub Actions / lint

Type '(pairs: KeyValuePairList) => PromiseExtended<(string | void | QueryResult)[]>' is not assignable to type '(pairs: KeyValuePairList) => Promise<void | BatchQueryResult | IDBValidKey[]>'.
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) => {

Check failure on line 65 in lib/storage/providers/DexieProvider.ts

View workflow job for this annotation

GitHub Actions / lint

Type '(pairs: KeyValuePairList) => PromiseExtended<string>' is not assignable to type '(pairs: KeyValuePairList) => Promise<void | BatchQueryResult>'.
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: () => {

Check failure on line 75 in lib/storage/providers/DexieProvider.ts

View workflow job for this annotation

GitHub Actions / lint

Type '() => PromiseExtended<IndexableTypeArray>' is not assignable to type '() => Promise<KeyList>'.
return db.keyvaluepairs.toCollection().keys();
},
getItem: (key) => {

Check failure on line 78 in lib/storage/providers/DexieProvider.ts

View workflow job for this annotation

GitHub Actions / lint

Type '<TKey extends string>(key: TKey) => PromiseExtended<{} | OnyxValue<TKey> | null>' is not assignable to type '<TKey extends string>(key: TKey) => Promise<OnyxValue<TKey>>'.
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;

0 comments on commit 85081c1

Please sign in to comment.