zustand-computed
Advanced tools
Comparing version 1.3.7 to 1.4.0
import { StateCreator, StoreApi, StoreMutatorIdentifier } from "zustand"; | ||
export declare type ComputedStateOpts<T> = { | ||
export type ComputedStateOpts<T> = { | ||
keys?: (keyof T)[]; | ||
@@ -7,9 +7,9 @@ disableProxy?: boolean; | ||
}; | ||
export declare type ComputedStateCreator = <T extends object, A extends object, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(f: StateCreator<T, [...Mps, ["chrisvander/zustand-computed", A]], Mcs>, compute: (state: T) => A, opts?: ComputedStateOpts<T>) => StateCreator<T, Mps, [["chrisvander/zustand-computed", A], ...Mcs], T & A>; | ||
declare type Cast<T, U> = T extends U ? T : U; | ||
declare type Write<T, U> = Omit<T, keyof U> & U; | ||
declare type StoreCompute<S, A> = S extends { | ||
export type ComputedStateCreator = <T extends object, A extends object, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = [], U = T>(f: StateCreator<T, [...Mps, ["chrisvander/zustand-computed", A]], Mcs>, compute: (state: T) => A, opts?: ComputedStateOpts<T>) => 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; | ||
declare type WithCompute<S, A> = Write<S, StoreCompute<S, A>>; | ||
type WithCompute<S, A> = Write<S, StoreCompute<S, A>>; | ||
declare module "zustand" { | ||
@@ -16,0 +16,0 @@ interface StoreMutators<S, A> { |
@@ -13,3 +13,5 @@ "use strict"; | ||
const selectorKeys = opts.keys; | ||
selectorKeys.forEach((key) => trackedSelectors.add(key)); | ||
for (const key of selectorKeys) { | ||
trackedSelectors.add(key); | ||
} | ||
} | ||
@@ -44,3 +46,5 @@ // we track which selectors are accessed | ||
const updated = typeof update === "object" ? update : update(state); | ||
if (useSelectors && trackedSelectors.size !== 0 && !Object.keys(updated).some((k) => trackedSelectors.has(k))) { | ||
if (useSelectors && | ||
trackedSelectors.size !== 0 && | ||
!Object.keys(updated).some((k) => trackedSelectors.has(k))) { | ||
// if we have a selector set, but none of the updated keys are in the selector set, then we can skip the compute | ||
@@ -47,0 +51,0 @@ return Object.assign(Object.assign({}, state), updated); |
import { StateCreator, StoreApi, StoreMutatorIdentifier } from "zustand"; | ||
export declare type ComputedStateOpts<T> = { | ||
export type ComputedStateOpts<T> = { | ||
keys?: (keyof T)[]; | ||
@@ -7,9 +7,9 @@ disableProxy?: boolean; | ||
}; | ||
export declare type ComputedStateCreator = <T extends object, A extends object, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(f: StateCreator<T, [...Mps, ["chrisvander/zustand-computed", A]], Mcs>, compute: (state: T) => A, opts?: ComputedStateOpts<T>) => StateCreator<T, Mps, [["chrisvander/zustand-computed", A], ...Mcs], T & A>; | ||
declare type Cast<T, U> = T extends U ? T : U; | ||
declare type Write<T, U> = Omit<T, keyof U> & U; | ||
declare type StoreCompute<S, A> = S extends { | ||
export type ComputedStateCreator = <T extends object, A extends object, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = [], U = T>(f: StateCreator<T, [...Mps, ["chrisvander/zustand-computed", A]], Mcs>, compute: (state: T) => A, opts?: ComputedStateOpts<T>) => 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; | ||
declare type WithCompute<S, A> = Write<S, StoreCompute<S, A>>; | ||
type WithCompute<S, A> = Write<S, StoreCompute<S, A>>; | ||
declare module "zustand" { | ||
@@ -16,0 +16,0 @@ interface StoreMutators<S, A> { |
@@ -9,3 +9,5 @@ import { shallow } from "zustand/shallow"; | ||
const selectorKeys = opts.keys; | ||
selectorKeys.forEach((key) => trackedSelectors.add(key)); | ||
for (const key of selectorKeys) { | ||
trackedSelectors.add(key); | ||
} | ||
} | ||
@@ -40,3 +42,5 @@ // we track which selectors are accessed | ||
const updated = typeof update === "object" ? update : update(state); | ||
if (useSelectors && trackedSelectors.size !== 0 && !Object.keys(updated).some((k) => trackedSelectors.has(k))) { | ||
if (useSelectors && | ||
trackedSelectors.size !== 0 && | ||
!Object.keys(updated).some((k) => trackedSelectors.has(k))) { | ||
// if we have a selector set, but none of the updated keys are in the selector set, then we can skip the compute | ||
@@ -43,0 +47,0 @@ return { ...state, ...updated }; |
{ | ||
"name": "zustand-computed", | ||
"version": "1.3.7", | ||
"version": "1.4.0", | ||
"description": "A Zustand middleware to create computed states.", | ||
@@ -5,0 +5,0 @@ "author": "chrisvander", |
@@ -29,6 +29,9 @@ # zustand-computed | ||
computed( | ||
(set) => ({ | ||
(set, get) => ({ | ||
count: 1, | ||
inc: () => set((state) => ({ count: state.count + 1 })), | ||
dec: () => set((state) => ({ count: state.count - 1 })), | ||
// get() function has access to ComputedStore | ||
square: () => set(() => ({ count: get().countSq })), | ||
root: () => set((state) => ({ count: Math.floor(Math.sqrt(state.count)) })), | ||
}), | ||
@@ -66,2 +69,5 @@ computeState | ||
dec: () => set((state) => ({ count: state.count - 1 })), | ||
// get() function has access to ComputedStore | ||
square: () => set(() => ({ count: get().countSq })), | ||
root: () => set((state) => ({ count: Math.floor(Math.sqrt(state.count)) })), | ||
}), | ||
@@ -95,4 +101,7 @@ computeState | ||
Here's an example with middleware. Works as expected. | ||
Here's an example with the Immer middleware. | ||
> [!WARNING] | ||
> Types may not be as you expect when using Immer, as it derives the SetState type from the output of GetState, where `zustand-computed` makes SetState only allow the regular Store and the GetState return both the store and the computed store. To access the ComputedStore inside Immer, you will need to assert the `Store` type as `Store & ComputedStore`. | ||
```ts | ||
@@ -99,0 +108,0 @@ const useStore = create<Store>()( |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16599
189
151