UNPKG

zustand-computed

Version:

A Zustand middleware to create computed states.

56 lines (55 loc) 2.58 kB
import { StateCreator, StoreApi, StoreMutatorIdentifier } from 'zustand'; /** * Options for when and how your compute function is called. */ export type ComputedStateOpts<T> = ({ /** * An explicit list of keys to track for recomputation. By default, * `zustand-computed` will run your compute function on any change. * This lets you filter those keys out. It's better to use the * `compareFn` to be more explicit about how comparison is determined. */ keys?: (keyof T)[]; } | { /** * Custom comparison function to determine whether to recompute. * Receives the previous and next store state, should return true if * compute should run, false to skip recomputation. This function * should be *fast* - it determines whether or not you need to * recompute. */ shouldRecompute?: (state: T, nextState: T) => boolean; }) & { /** * @deprecated removed proxy; this does nothing and will be removed. */ disableProxy?: boolean; /** * Custom equality function for comparing computed values. By default, we use * `zustand/shallow` to compare each key in your store against the newly- * computed values. This is likely the desired method of comparison. * * The motivation for this function is to ensure that, in the case your * computed function returns a value that is identical structurally, it * should not cause a re-render despite the reference being different. * * You can disable comparison, so that the most recent result of the * compute function always triggers downstream re-renders, by simply * returning false. */ equalityFn?: <Y>(a: Y, b: Y) => boolean; }; export type ComputedStateCreator = <T extends object, A extends object>(compute: (state: T) => A, opts?: ComputedStateOpts<T>) => <Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = [], U = T>(f: StateCreator<T, [...Mps, ["chrisvander/zustand-computed", A]], Mcs>) => StateCreator<T, Mps, [["chrisvander/zustand-computed", A], ...Mcs], U & A>; type Cast<T, U> = T extends U ? T : U; type Write<T, U> = Omit<T, keyof U> & U; type StoreCompute<S, A> = S extends { getState: () => infer T; } ? Omit<StoreApi<T & A>, "setState"> : never; type WithCompute<S, A> = Write<S, StoreCompute<S, A>>; declare module "zustand/vanilla" { interface StoreMutators<S, A> { "chrisvander/zustand-computed": WithCompute<Cast<S, object>, A>; } } export declare const createComputed: ComputedStateCreator; export {};