zustand-lite
Version:
Zustand Lite builds upon zustand, by auto-generating selectors and simplifying API even more.
81 lines (75 loc) • 4.31 kB
text/typescript
import { StoreApi as StoreApi$1 } from 'zustand';
import { DevtoolsOptions, PersistOptions } from 'zustand/middleware';
type State = Record<string | symbol, unknown>;
type Empty = Record<string, never>;
type Default = Record<string | symbol, any>;
type EqualityChecker<S> = (state: S, newState: S) => boolean;
type StoreApiEncapsulated<S extends State = Empty, Getters = Default, Setters = Default> = {
api: Omit<StoreApi$1<S>, 'setState' | 'getState'>;
get: GetRecord<S> & Getters;
set: SetRecord<S> & Setters;
use: UseRecord<S> & Getters;
};
type StoreApi<S extends State = Empty, Getters = Default, Setters = Default> = {
api: Omit<StoreApi$1<S>, 'setState' | 'getState'>;
get: GetRecord<S> & Getters;
set: SetRecord<S> & Setters;
use: UseRecord<S> & Getters;
extendGetters<Builder extends GettersBuilder<S, Getters>>(builder: Builder): StoreApi<S, Getters & ReturnType<Builder>, Setters>;
extendSetters<Builder extends SettersBuilder<S, Getters, Setters>>(builder: Builder): StoreApi<S, Getters, Setters & ReturnType<Builder>>;
restrictState(): StoreApiEncapsulated<S, Getters, Setters>;
restrictState<Key extends keyof S>(publicState: Key[]): StoreApiEncapsulated<Omit<S, Key>, Getters, Setters>;
};
type GettersBuilder<S extends State, Getters = Default> = (args: {
get: GetRecord<S> & Getters;
}) => Record<string, (...args: any[]) => any>;
type SettersBuilder<S extends State, Getters = Default, Setters = Default> = (args: {
api: Omit<StoreApi$1<S>, 'setState' | 'getState'>;
get: GetRecord<S> & Getters;
set: SetRecord<S> & Setters;
}) => Record<string, (...args: any[]) => void>;
type GetRecord<S extends Record<string, any>> = () => S;
type SetRecord<S extends Record<string, any>> = StoreApi$1<S>['setState'] & {
[K in keyof S]-?: (value: S[K]) => void;
};
type UseRecord<S, R = any> = UseRecordDeep<S> & ((selector: (state: S) => R, equality?: EqualityChecker<S>) => R);
type UseRecordDeep<S> = {
[K in keyof S]-?: S[K] extends Record<string, any> ? IsOptional<S, K> extends false ? ((equalityFn?: EqualityChecker<S[K]>) => S[K]) & UseRecordDeep<S[K]> : never : (equalityFn?: EqualityChecker<S[K]>) => S[K];
};
type IsOptional<S, K extends keyof S> = undefined extends S[K] ? {} extends Pick<S, K> ? true : false : false;
type StoreApiPlugin<NewApiData extends State, NewGetters, NewSetters> = {
creates?: () => NewApiData;
extends?: (store: StoreApi<NewApiData, NewGetters, NewSetters>) => StoreApi<NewApiData, NewGetters, NewSetters>;
};
type StoreApiPluginList = StoreApiPlugin<any, any, any>[];
type AugmentedApiData<S, Plugins extends StoreApiPluginList> = S & UnionToIntersection<ExtractPluginTypes<Plugins, 'create'>[number]>;
type AugmentedGetters<Plugins extends StoreApiPluginList> = UnionToIntersection<ExtractPluginTypes<Plugins, 'extend'>[number]['getters']>;
type AugmentedSetters<Plugins extends StoreApiPluginList> = UnionToIntersection<ExtractPluginTypes<Plugins, 'extend'>[number]['setters']>;
type ExtractPluginTypes<Plugins extends StoreApiPluginList, Key extends 'create' | 'extend'> = {
[K in keyof Plugins]: Plugins[K] extends StoreApiPlugin<infer S, infer G, infer A> ? Key extends 'create' ? S : Key extends 'extend' ? {
getters: G;
setters: A;
} : never : never;
};
type UnionToIntersection<S> = (S extends any ? (k: S) => void : never) extends (k: infer I) => void ? I : never;
/**
* Entire zustand-lite no-boilerplate functionality is inspired by this recipe:
* https://docs.pmnd.rs/zustand/guides/auto-generating-selectors and 3th party
* zustand-x repository: https://github.com/udecode/zustand-x.
**/
declare function createStore<S extends State, Plugins extends StoreApiPluginList = []>(initialState: S, options?: {
name?: string;
plugins?: [...Plugins];
middlewares?: {
devtools?: true | DevtoolsOptions;
persist?: true | PersistOptions<any>;
};
}): Plugins extends [] ? StoreApi<S> : StoreApi<AugmentedApiData<S, Plugins>, AugmentedGetters<Plugins>, AugmentedSetters<Plugins>>;
type PluginResetSetters = {
reset: () => void;
};
/**
* Basic plugin example, that extends store with custom setter.
*/
declare const reset: StoreApiPlugin<{}, {}, PluginResetSetters>;
export { type StoreApiPlugin, createStore, reset };