diff options
author | Eric Bailey <git@esb.lol> | 2024-09-05 14:31:24 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-05 12:31:24 -0700 |
commit | 8a66883df8fa19290e9754c554faf36a4c3090d5 (patch) | |
tree | 4fca7de046372f0fe825ede0b5803d950ec6186d /src/storage/index.ts | |
parent | 2265fedd2ac4d006e3c55dbb81ee387b93be9830 (diff) | |
download | voidsky-8a66883df8fa19290e9754c554faf36a4c3090d5.tar.zst |
Add MMKV interface (#5169)
Diffstat (limited to 'src/storage/index.ts')
-rw-r--r-- | src/storage/index.ts | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/storage/index.ts b/src/storage/index.ts new file mode 100644 index 000000000..819ffab7e --- /dev/null +++ b/src/storage/index.ts @@ -0,0 +1,72 @@ +import {MMKV} from 'react-native-mmkv' + +import {Device} from '#/storage/schema' + +/** + * Generic storage class. DO NOT use this directly. Instead, use the exported + * storage instances below. + */ +export class Storage<Scopes extends unknown[], Schema> { + protected sep = ':' + protected store: MMKV + + constructor({id}: {id: string}) { + this.store = new MMKV({id}) + } + + /** + * Store a value in storage based on scopes and/or keys + * + * `set([key], value)` + * `set([scope, key], value)` + */ + set<Key extends keyof Schema>( + scopes: [...Scopes, Key], + data: Schema[Key], + ): void { + // stored as `{ data: <value> }` structure to ease stringification + this.store.set(scopes.join(this.sep), JSON.stringify({data})) + } + + /** + * Get a value from storage based on scopes and/or keys + * + * `get([key])` + * `get([scope, key])` + */ + get<Key extends keyof Schema>( + scopes: [...Scopes, Key], + ): Schema[Key] | undefined { + const res = this.store.getString(scopes.join(this.sep)) + if (!res) return undefined + // parsed from storage structure `{ data: <value> }` + return JSON.parse(res).data + } + + /** + * Remove a value from storage based on scopes and/or keys + * + * `remove([key])` + * `remove([scope, key])` + */ + remove<Key extends keyof Schema>(scopes: [...Scopes, Key]) { + this.store.delete(scopes.join(this.sep)) + } + + /** + * Remove many values from the same storage scope by keys + * + * `removeMany([], [key])` + * `removeMany([scope], [key])` + */ + removeMany<Key extends keyof Schema>(scopes: [...Scopes], keys: Key[]) { + keys.forEach(key => this.remove([...scopes, key])) + } +} + +/** + * Device data that's specific to the device and does not vary based on account + * + * `device.set([key], true)` + */ +export const device = new Storage<[], Device>({id: 'device'}) |