Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11x 11x 11x 11x 11x 11x 11x 11x 11x 14x 11x 11x 11x 11x 11x 3x 3x 3x 3x 3x 3x 11x 11x 11x 11x 11x 11x 11x 11x 11x 3x 3x 11x 11x 11x 11x | import { AnyFunc, DerivedStore, Store } from "../types";
import { withUse } from "../withUse";
import { emitter } from "../emitter";
/**
* Create a derived (computed) store from one or more source stores.
*
* Derived stores are read-only and automatically update when any
* dependency store changes. Useful for computing derived state.
*
* @example
* ```ts
* const totalStore = derived(
* "total",
* [priceStore, quantityStore],
* (price, quantity) => price * quantity
* );
* ```
*
* @param name - Identifier for the derived store
* @param dependencies - Array of source stores to derive from
* @param selector - Function that computes the derived value
* @returns A read-only DerivedStore
*/
export function derived<T, const TStores extends readonly Store<any>[]>(
name: string,
dependencies: TStores,
selector: (
...args: {
[K in keyof TStores]: TStores[K] extends Store<infer T> ? T : never;
}
) => T
): DerivedStore<T> {
const getDerivedState = () =>
(selector as AnyFunc)(...dependencies.map((d) => d.getState()));
let currentState = getDerivedState();
const changeEmitter = emitter<void>();
const checkUpdates = () => {
const newState = getDerivedState();
if (newState !== currentState) {
currentState = newState;
changeEmitter.emit();
}
};
// Subscribe to all dependencies
dependencies.forEach((d) => d.onChange(checkUpdates));
const derivedStore: DerivedStore<T> = withUse({
name,
dependencies,
getState: () => currentState,
onChange: (listener: () => void) => {
return changeEmitter.on(listener);
},
});
return derivedStore;
}
|