@vantezzen/plasmo-state
Version:
♻️ Sync state across content script, background workers and the popup in Plasmo extensions
130 lines (124 loc) • 3.84 kB
TypeScript
import EventEmitter from 'events';
/**
* Environment that hosts the current State instance
*/
declare enum StateEnvironment {
Popup = "popup",
Background = "background",
Content = "content",
Offscreen = "offscreen"
}
/**
* Configuration for the state
*/
declare type SetupConfig<T> = {
persistent?: (keyof T)[];
tabId?: number;
};
/**
* Messages sent internally for synchronization
*/
declare type SyncMessage<T> = {
type: "sync";
action: "push" | "pull" | "tabId" | "pushStateOffscreen" | "pullStateOffscreen";
data?: T;
payload?: T;
tabId: number;
};
declare type ChangeSource = "user" | "content" | "background" | "storage" | "sync" | "offscreen";
/**
* Central state management class.
*/
declare class State<T extends object> extends EventEmitter {
#private;
setupDone: boolean;
currentSource: ChangeSource;
constructor(environment: StateEnvironment, initialState: T, config?: SetupConfig<T>);
/**
* Internal method to increase the ready progress
* This is used to determine if the state is ready to be used
*
* Do not call this manually!
*/
increaseReadyProgress(): void;
/**
* Get the current state as a proxy object.
*
* This allows direct modification of the object without helper classes like "set" or "merge".
*/
get current(): T;
/**
* Gets the current state as a raw object.
* Please note that this is NOT a proxy object. Do not modify it as changes will not be synced and may be overridden at any time
*/
get currentRaw(): Readonly<T>;
/**
* Get the current tab ID that is used for syncing
*/
get tabId(): number;
/**
* Get the current environment this instance is set to work in
*/
get environment(): StateEnvironment;
/**
* Checks if a key should be persisted in the browser storage
*
* @param key Key to check
* @returns
*/
keyIsPersistent(key: keyof T): boolean;
/**
* Please the state object with new values without merging.
* This is mostly used internally and should NOT be used for changing individual values.
* Changes may not be synced - use the Proxy for that
*
* @param state New state object
*/
replace(state: T, source: ChangeSource): void;
/**
* Destroy the instance and clean up.
* This will remove all listeners and stops syncing to enable the instance to be garbage collected.
*
* After detroying the instance, it is not possible to use it anymore!
*/
destroy(): void;
/**
* Check if the instance is destroyed
*/
get isDestroyed(): boolean;
/**
* Ensure that the state is not already destroyed, otherwise throw
*/
ensureNotDestroyed(): void;
/**
* Force the state to be pulled from other environments
*/
forcePull(): Promise<void>;
}
/**
* Use a plasmo-state instance inside a react component
* This will automatically re-render when the state changes.
*
* The return value is the proxy of the state object. You can
* directly modify its properties without needing to call a
* function like "setState".
*
* Usage:
* const myState = setupState(...);
*
* () => {
* const state = usePlasmoState(myState);
* return (
* <div>
* {state.couter}
* <button onClick={() => state.counter++}>Increment</button>
* </div>
* );
* }
*
* @param state The plasmo-state instance
* @returns The current state proxy
*/
declare function usePlasmoState<T extends object>(state: State<T>): T;
declare function setupState<T extends object>(environment: StateEnvironment, initialState: T, config?: SetupConfig<T>): State<T>;
export { ChangeSource, SetupConfig, State, StateEnvironment, SyncMessage, setupState as default, usePlasmoState };