crann
Version:
Effortless State Synchronization for Web Extensions
110 lines (109 loc) • 5.02 kB
TypeScript
import { AgentInfo, BrowserLocation } from "../transport";
export declare const Partition: {
Instance: "instance";
Service: "service";
};
export declare const Persistence: {
Session: "session";
Local: "local";
None: "none";
};
export type ActionHandler<TState, TArgs extends any[], TResult> = (state: TState, setState: SetStateFunction<TState>, target: BrowserLocation, ...args: TArgs) => Promise<TResult>;
export type ActionDefinition<TState, TArgs extends any[], TResult> = {
handler: ActionHandler<TState, TArgs, TResult>;
validate?: (...args: TArgs) => void;
};
export type ActionsConfig<TState> = {
[K: string]: ActionDefinition<TState, any[], Partial<TState>>;
};
export type SetStateFunction<TState> = {
(state: Partial<TState>): Promise<void>;
(state: Partial<TState>, key: string): Promise<void>;
};
export type SetStateCallback<TConfig extends AnyConfig> = {
(state: Partial<DerivedServiceState<TConfig>>): Promise<void>;
(state: Partial<DerivedInstanceState<TConfig>>, key: string): Promise<void>;
};
export type ConfigItem<T> = {
default: T;
partition?: (typeof Partition)[keyof typeof Partition];
persist?: (typeof Persistence)[keyof typeof Persistence];
};
export type AnyConfig = Record<string, ConfigItem<any> | ActionDefinition<any, any[], any>>;
export type StateConfig<T extends AnyConfig> = {
[P in keyof T]: T[P] extends ConfigItem<any> ? T[P] : never;
};
export type ActionConfig<T extends AnyConfig> = {
[P in keyof T]: T[P] extends ActionDefinition<any, any[], any> ? T[P] : never;
};
export type DerivedState<T extends AnyConfig> = {
[P in keyof T]: T[P] extends ConfigItem<infer DefaultType> ? DefaultType : never;
};
export type DerivedInstanceState<T extends AnyConfig> = {
[P in keyof T]: T[P] extends ConfigItem<infer DefaultType> & {
partition: "instance";
} ? DefaultType : never;
};
export type DerivedServiceState<T extends AnyConfig> = {
[P in keyof T]: T[P] extends ConfigItem<infer DefaultType> ? T[P] extends {
partition: "instance";
} ? never : DefaultType : never;
};
type OmitNever<T> = {
[K in keyof T as T[K] extends never ? never : K]: T[K];
};
export type MergeStateTypes<TInstance, TService> = OmitNever<TInstance> & OmitNever<TService>;
export declare const isStateItem: <T>(item: ConfigItem<T> | ActionDefinition<any, any[], any>) => item is ConfigItem<T>;
export declare const isActionItem: <TState, TArgs extends any[], TResult>(item: ConfigItem<any> | ActionDefinition<TState, TArgs, TResult>) => item is ActionDefinition<TState, TArgs, TResult>;
type StateSubscriber<TConfig extends AnyConfig> = {
keys?: Array<keyof DerivedState<TConfig>>;
callback: (changes: StateUpdate<TConfig>) => void;
};
type CrannAgent<TConfig extends AnyConfig> = {
get: () => DerivedState<TConfig>;
set: (update: StateUpdate<TConfig>) => void;
subscribe: (callback: (changes: StateUpdate<TConfig>) => void, keys?: Array<keyof TConfig>) => () => void;
getAgentInfo: () => AgentInfo;
onReady: (callback: (info: ConnectionStatus) => void) => () => void;
};
type UseCrann<TConfig extends AnyConfig> = <K extends keyof DerivedState<TConfig>>(key: K) => [
DerivedState<TConfig>[K],
(value: DerivedState<TConfig>[K]) => void,
(callback: (update: StateChangeUpdate<TConfig, K>) => void) => () => void
];
type ConnectReturn<TConfig extends AnyConfig> = {
useCrann: UseCrann<TConfig>;
get: CrannAgent<TConfig>["get"];
set: CrannAgent<TConfig>["set"];
subscribe: CrannAgent<TConfig>["subscribe"];
getAgentInfo: CrannAgent<TConfig>["getAgentInfo"];
onReady: CrannAgent<TConfig>["onReady"];
callAction: (name: string, ...args: any[]) => Promise<any>;
onDisconnect: (callback: () => void) => () => void;
onReconnect: (callback: (info: AgentInfo) => void) => () => void;
};
export type StateChanges<T extends AnyConfig> = {
[K in keyof DerivedState<T>]?: NonNullable<DerivedState<T>[K]>;
};
type StateChangeUpdate<TConfig extends AnyConfig, K extends keyof DerivedState<TConfig>> = {
current: DerivedState<TConfig>[K];
previous: DerivedState<TConfig>[K];
state: DerivedState<TConfig>;
};
export type StateChangeListener<TConfig extends AnyConfig> = (state: DerivedInstanceState<TConfig> | DerivedState<TConfig>, changes: StateChanges<TConfig>, agent?: AgentInfo) => void;
type AgentSubscription<TConfig extends AnyConfig> = {
(callback: (changes: StateUpdate<TConfig>) => void, key?: keyof DerivedState<TConfig>): number;
};
type StateUpdate<TConfig extends AnyConfig> = StateChanges<TConfig>;
export type CrannOptions = {
debug?: boolean;
storagePrefix?: string;
};
type ConnectionStatus = {
connected: boolean;
agent?: AgentInfo;
};
export type CrannConfig<TState> = {
[K: string]: ConfigItem<any> | ActionsConfig<TState>;
};
export { StateSubscriber, CrannAgent, AgentSubscription, StateUpdate, DerivedState as State, ConnectReturn, UseCrann, ConnectionStatus, StateChangeUpdate, };