Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wip): dexie provider for the web platform #2

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/storage/platforms/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import WebStorage from '../providers/IDBKeyValProvider';
import WebStorage from '../providers/DexieProvider';

export default WebStorage;
108 changes: 108 additions & 0 deletions lib/storage/providers/DexieProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// TODO: Fix types
import Dexie from 'dexie';
import utils from '../../utils';
import type StorageProvider from './types';
import type {OnyxKey, OnyxValue} from '../../types';

class OnyxDatabase extends Dexie {
keyvaluepairs!: Dexie.Table<OnyxValue<OnyxKey>, OnyxKey>;

constructor() {
super('OnyxDB');
this.version(0.1).stores({
keyvaluepairs: '',
});
}
}

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',
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) {
return provider.removeItem(key);
}
return db.keyvaluepairs.put(value, key);
},
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) => {

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;
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
},
"dependencies": {
"ascii-table": "0.0.9",
"dexie": "^4.0.8",
"fast-equals": "^4.0.3",
"underscore": "^1.13.6"
},
Expand Down
Loading