@livetl/svelte-webext-stores
Version:
Svelte stores that synchronizes to WebExtension storage.
214 lines (204 loc) • 8.61 kB
TypeScript
/// <reference types="chrome" />
import { Readable } from 'svelte/store';
interface StorageChange {
newValue?: any;
oldValue?: any;
}
declare type StorageChanges = Record<string, StorageChange>;
declare type OnChangedCallback = (changes: StorageChanges) => void;
/** Interface for storage backends. */
interface IStorageBackend {
/**
* Get value from storage backend.
* @param key Storage key.
*/
get: <T>(key: string) => Promise<T | undefined>;
/**
* Set value in storage backend.
* @param key Storage key.
* @param value Value to set.
*/
set: <T>(key: string, value: T) => Promise<void>;
/**
* Add listener for storage change events.
* @param callback Callback function when onChanged event is triggered.
*/
addOnChangedListener: (callback: OnChangedCallback) => void;
/** Perform clean up operations. */
cleanUp: () => void;
/** Remove item with given key from storage. */
remove: (key: string) => Promise<void>;
/** Clears all stored values from storage backend. */
clear: () => Promise<void>;
}
declare type WebExtStorageArea = 'local' | 'sync' | 'managed';
/** Storage backend for Mozilla WebExtension (browser API). */
interface StorageWebExt extends IStorageBackend {
}
/**
* Create storage backend for Mozilla WebExtension (browser API).
* @param area `'local'` | `'sync'` | `'managed'`. Default: `'local'`
*/
declare function storageWebExt(area?: WebExtStorageArea): StorageWebExt;
/** Storage backend for Chrome Manifest Version 2 (callback API). */
interface StorageMV2 extends IStorageBackend {
}
/**
* Create storage backend for Chrome Manifest Version 2 (callback API).
* @param area `'local'` | `'sync'` | `'managed'`. Default: `'local'`
*/
declare function storageMV2(area?: WebExtStorageArea): StorageMV2;
/** Storage backend for Chrome Manifest Version 3 (Promise API). */
interface StorageMV3 extends IStorageBackend {
}
/**
* Create storage backend for Chrome Manifest Version 3 (Promise API).
* @param area `'local'` | `'sync'` | `'managed'`. Default: `'local'`
*/
declare function storageMV3(area?: WebExtStorageArea): StorageMV3;
declare type WebStorageType = 'session' | 'local';
/**
* Storage backend for legacy/non-WebExtension applications
* (`localStorage` or `sessionStorage`).
*/
interface StorageLegacy extends IStorageBackend {
}
/**
* Create storage backend for legacy/non-WebExtension applications.
* @param area `'session'` | `'local'`. Default: `'session'`.
*/
declare function storageLegacy(area?: WebStorageType): StorageLegacy;
/** Interface for stores that is synchronized to storage. */
interface ISyncStore<T> extends Readable<T> {
/** Get current value after updating from backend. */
get: () => Promise<T>;
/**
* Set value, inform subscribers, and push to storage.
* @param value to set
*/
set: (value: T) => Promise<void>;
/**
* Set value, inform subscribers without pushing to storage.
* @param value to set
*/
setRaw: (value: T) => void;
/**
* Get current value without updating from backend.
*
* Used for comparing storage changes when syncing from storage.
*/
getCurrent: () => T;
/**
* Whether store should be updated when storage value is updated externally,
* e.g. storage value is changed by another page.
*/
readonly syncFromExternal: boolean;
/** Storage item key. */
readonly key: string;
}
interface VersionedOptions<T> {
/** Current version number. Do not use `-1`. */
version: number;
/** Separator between key and version. */
seperator: string;
/**
* Map for migrating values.
*
* Keys are the old version to match against, and values are callbacks that
* accepts the value found from the given old version and returns the
* corresponding value for the current version.
*
* Use the key `-1` to migrate from a versionless store.
*/
migrations?: Map<number, (oldValue: any) => T>;
}
/** Store that is synchronized to the storage backend. */
interface SyncStore<T> extends ISyncStore<T> {
/**
* Ensure that any async initialization process (such as initial update
* from backend) has been completed.
*
* You typically don't need to manually await unless you wish to sync
* the store to the storage backend before any of `get()`, `set()` or
* `subscribe()` is called.
*/
ready: () => Promise<void>;
/** Reset store value to default value. */
reset: () => Promise<void>;
/**
* Update value using callback and inform subscribers.
* @param updater callback
*/
update: (updater: (value: T) => T) => Promise<void>;
}
/**
* Create a store that is synchronized to the storage backend.
* @param key Storage key.
* @param defaultValue Item default value.
* @param backend Storage backend.
* @param syncFromExternal Whether store should be updated when storage value
* is updated externally.
* @param versionedOptions Enables options for migrating storage values from an
* older version to a newer version.
*/
declare function syncStore<T>(key: string, defaultValue: T, backend: IStorageBackend, syncFromExternal: boolean, versionedOptions?: VersionedOptions<T>): SyncStore<T>;
declare type ILookupStore<T extends Record<string, any>, S extends ISyncStore<T>> = S & {
/** Get object property value. */
getItem: <R extends T[keyof T]>(key: keyof T) => Promise<R>;
/** Set object property value. */
setItem: <V extends T[keyof T]>(key: keyof T, value: V) => Promise<void>;
};
/**
* SyncStore for `Record<string, any>` objects. Provides convenience methods
* for getting and setting property values using property keys.
*/
declare type LookupStore<T extends Record<string, any>> = ILookupStore<T, SyncStore<T>>;
declare function addLookupMethods<T extends Record<string, any>, S extends ISyncStore<T>>(store: S): ILookupStore<T, S>;
/**
* Handler for registering stores that are synced to storage.
* This handler will listen to storage changes and automatically update
* registered stores if needed.
*/
interface WebExtStores {
/**
* Registers and returns a new SyncStore.
* @param key Storage key.
* @param defaultValue Store's default value.
* @param syncFromExternal Whether store should be updated when storage
* value is updated externally. Default: `true`.
* @param versionedOptions Enables options for migrating storage values from
* an older version to a newer version.
*/
addSyncStore: <T>(key: string, defaultValue: T, syncFromExternal?: boolean, versionedOptions?: VersionedOptions<T>) => SyncStore<T>;
/**
* Registers and returns a new Lookupable SyncStore.
* @param key Storage key.
* @param defaultValue Store's default value.
* @param syncFromExternal Whether store should be updated when storage
* value is updated externally. Default: `true`.
* @param versionedOptions Enables options for migrating storage values from
* an older version to a newer version.
*/
addLookupStore: <T extends Record<string, any>>(key: string, defaultValue: T, syncFromExternal?: boolean, versionedOptions?: VersionedOptions<T>) => LookupStore<T>;
/**
* Registers a custom store that implements ISyncStore.
* @param getStore Callback that provides the handler's StorageBackend and
* expects an ISyncStore implementation.
*/
addCustomStore: <S extends ISyncStore<unknown>>(getStore: (backend: IStorageBackend) => S) => S;
/**
* Removes and unregisters all registered stores from backend storage.
* For tests purposes only.
*/
_clear: () => Promise<void>;
/** Export all registered stores as JSON string. */
exportJson: () => Promise<string>;
/** Import store values from JSON string. */
importJson: (json: string) => Promise<void>;
}
/**
* Create handler for registering stores that are synced to storage.
* @param backend Storage backend.
*/
declare function webExtStores(backend?: IStorageBackend): WebExtStores;
export { IStorageBackend, ISyncStore, OnChangedCallback, StorageChange, StorageChanges, StorageLegacy, StorageMV2, StorageMV3, StorageWebExt, SyncStore, VersionedOptions, WebExtStores, addLookupMethods, storageLegacy, storageMV2, storageMV3, storageWebExt, syncStore, webExtStores };