diff --git a/plugins/store/guest-js/index.ts b/plugins/store/guest-js/index.ts index 1df89fd5..a3c3f4ce 100644 --- a/plugins/store/guest-js/index.ts +++ b/plugins/store/guest-js/index.ts @@ -36,6 +36,10 @@ export type StoreOptions = { createNew?: boolean } +interface StoreEntries { + [key: string]: unknown +} + /** * Create a new Store or load the existing store with the path. * @@ -48,10 +52,10 @@ export type StoreOptions = { * @param path Path to save the store in `app_data_dir` * @param options Store configuration options */ -export async function load( +export async function load( path: string, options?: StoreOptions -): Promise { +): Promise> { return await Store.load(path, options) } @@ -71,19 +75,19 @@ export async function load( * * @param path Path of the store. */ -export async function getStore(path: string): Promise { - return await Store.get(path) +export async function getStore(path: string): Promise | null> { + return await Store.get(path) } /** * A lazy loaded key-value store persisted by the backend layer. */ -export class LazyStore implements IStore { - private _store?: Promise +export class LazyStore implements IStore { + private _store?: Promise> - private get store(): Promise { + private get store(): Promise> { if (!this._store) { - this._store = load(this.path, this.options) + this._store = load(this.path, this.options) } return this._store } @@ -105,20 +109,20 @@ export class LazyStore implements IStore { await this.store } - async set(key: string, value: unknown): Promise { + async set(key: K, value: S[K]): Promise { return (await this.store).set(key, value) } - async get(key: string): Promise { - return (await this.store).get(key) + async get(key: K): Promise { + return (await this.store).get(key) } - async has(key: string): Promise { - return (await this.store).has(key) + async has(key: K): Promise { + return (await this.store).has(key) } - async delete(key: string): Promise { - return (await this.store).delete(key) + async delete(key: K): Promise { + return (await this.store).delete(key) } async clear(): Promise { @@ -129,16 +133,16 @@ export class LazyStore implements IStore { await (await this.store).reset() } - async keys(): Promise { - return (await this.store).keys() + async keys(): Promise { + return (await this.store).keys() } - async values(): Promise { + async values(): Promise { return (await this.store).values() } - async entries(): Promise> { - return (await this.store).entries() + async entries(): Promise> { + return (await this.store).entries() } async length(): Promise { @@ -153,17 +157,17 @@ export class LazyStore implements IStore { await (await this.store).save() } - async onKeyChange( - key: string, - cb: (value: T | undefined) => void + async onKeyChange( + key: K, + cb: (value: S[K] | undefined) => void ): Promise { - return (await this.store).onKeyChange(key, cb) + return (await this.store).onKeyChange(key, cb) } - async onChange( - cb: (key: string, value: T | undefined) => void + async onChange( + cb: (key: K, value: S[K] | undefined) => void ): Promise { - return (await this.store).onChange(cb) + return (await this.store).onChange(cb) } async close(): Promise { @@ -176,7 +180,7 @@ export class LazyStore implements IStore { /** * A key-value store persisted by the backend layer. */ -export class Store extends Resource implements IStore { +export class Store extends Resource implements IStore { private constructor(rid: number) { super(rid) } @@ -193,7 +197,7 @@ export class Store extends Resource implements IStore { * @param path Path to save the store in `app_data_dir` * @param options Store configuration options */ - static async load(path: string, options?: StoreOptions): Promise { + static async load(path: string, options?: StoreOptions): Promise> { const rid = await invoke('plugin:store|load', { path, ...options @@ -220,13 +224,13 @@ export class Store extends Resource implements IStore { * * @param path Path of the store. */ - static async get(path: string): Promise { + static async get(path: string): Promise | null> { return await invoke('plugin:store|get_store', { path }).then( (rid) => (rid ? new Store(rid) : null) ) } - async set(key: string, value: unknown): Promise { + async set(key: K, value: S[K]): Promise { await invoke('plugin:store|set', { rid: this.rid, key, @@ -234,22 +238,22 @@ export class Store extends Resource implements IStore { }) } - async get(key: string): Promise { - const [value, exists] = await invoke<[T, boolean]>('plugin:store|get', { + async get(key: K): Promise { + const [value, exists] = await invoke<[S[K], boolean]>('plugin:store|get', { rid: this.rid, key }) return exists ? value : undefined } - async has(key: string): Promise { + async has(key: K): Promise { return await invoke('plugin:store|has', { rid: this.rid, key }) } - async delete(key: string): Promise { + async delete(key: K): Promise { return await invoke('plugin:store|delete', { rid: this.rid, key @@ -264,15 +268,15 @@ export class Store extends Resource implements IStore { await invoke('plugin:store|reset', { rid: this.rid }) } - async keys(): Promise { + async keys(): Promise { return await invoke('plugin:store|keys', { rid: this.rid }) } - async values(): Promise { + async values(): Promise { return await invoke('plugin:store|values', { rid: this.rid }) } - async entries(): Promise> { + async entries(): Promise> { return await invoke('plugin:store|entries', { rid: this.rid }) } @@ -288,23 +292,24 @@ export class Store extends Resource implements IStore { await invoke('plugin:store|save', { rid: this.rid }) } - async onKeyChange( - key: string, - cb: (value: T | undefined) => void + async onKeyChange( + key: K, + cb: (value: S[K] | undefined) => void ): Promise { - return await listen>('store://change', (event) => { + return await listen>('store://change', (event) => { if (event.payload.resourceId === this.rid && event.payload.key === key) { cb(event.payload.exists ? event.payload.value : undefined) } }) } - async onChange( - cb: (key: string, value: T | undefined) => void + async onChange( + cb: (key: K, value: S[K] | undefined) => void ): Promise { - return await listen>('store://change', (event) => { + return await listen>('store://change', (event) => { if (event.payload.resourceId === this.rid) { cb( + // @ts-ignore Typescript complains that `key` can be of type `string | number | symbol`. Doesn't affect end-user. event.payload.key, event.payload.exists ? event.payload.value : undefined ) @@ -321,7 +326,7 @@ interface IStore { * @param value * @returns */ - set(key: string, value: unknown): Promise + set(key: K, value: StoreEntries[K]): Promise /** * Returns the value for the given `key` or `undefined` if the key does not exist. @@ -329,7 +334,7 @@ interface IStore { * @param key * @returns */ - get(key: string): Promise + get(key: K): Promise /** * Returns `true` if the given `key` exists in the store. @@ -337,7 +342,7 @@ interface IStore { * @param key * @returns */ - has(key: string): Promise + has(key: K): Promise /** * Removes a key-value pair from the store. @@ -345,7 +350,7 @@ interface IStore { * @param key * @returns */ - delete(key: string): Promise + delete(key: K): Promise /** * Clears the store, removing all key-value pairs. @@ -368,21 +373,21 @@ interface IStore { * * @returns */ - keys(): Promise + keys(): Promise /** * Returns a list of all values in the store. * * @returns */ - values(): Promise + values(): Promise /** * Returns a list of all entries in the store. * * @returns */ - entries(): Promise> + entries(): Promise> /** * Returns the number of key-value pairs in the store. @@ -415,9 +420,9 @@ interface IStore { * * @since 2.0.0 */ - onKeyChange( - key: string, - cb: (value: T | undefined) => void + onKeyChange( + key: K, + cb: (value: StoreEntries[K] | undefined) => void ): Promise /** @@ -427,8 +432,8 @@ interface IStore { * * @since 2.0.0 */ - onChange( - cb: (key: string, value: T | undefined) => void + onChange( + cb: (key: keyof StoreEntries, value: StoreEntries[keyof StoreEntries] | undefined) => void ): Promise /**