reselect-kit 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +307 -36
  2. package/dist/cjs/reselectKit.development.cjs +256 -95
  3. package/dist/cjs/reselectKit.development.cjs.map +1 -1
  4. package/dist/cjs/reselectKit.production.min.cjs +1 -1
  5. package/dist/cjs/reselectKit.production.min.cjs.map +1 -1
  6. package/dist/reselectKit.d.ts +201 -92
  7. package/dist/reselectKit.mjs +257 -97
  8. package/dist/reselectKit.mjs.map +1 -1
  9. package/package.json +1 -1
  10. package/src/__tests__/createAdaptedSelector.test.ts +3 -4
  11. package/src/__tests__/createBoundSelector.test.ts +92 -5
  12. package/src/__tests__/createChainSelector.bench.ts +117 -0
  13. package/src/__tests__/createChainSelector.test.ts +162 -6
  14. package/src/__tests__/createPathSelector.test.ts +14 -0
  15. package/src/__tests__/createSequenceSelector.test.ts +10 -14
  16. package/src/_helpers/__tests__/generateSelectorKey.test.ts +24 -0
  17. package/src/_helpers/__tests__/getSelectorName.test.ts +30 -0
  18. package/src/_helpers/unfreezeProps.ts +14 -0
  19. package/src/_hooks/__tests__/useSelector.bench.ts +133 -0
  20. package/src/_hooks/__tests__/useSelector.test.ts +69 -0
  21. package/src/_hooks/__tests__/useSelectors.bench.ts +160 -0
  22. package/src/_hooks/__tests__/useSelectors.test.ts +219 -0
  23. package/src/_hooks/selectorOptions.ts +11 -0
  24. package/src/_hooks/useSelector.ts +68 -26
  25. package/src/_hooks/useSelectors.ts +162 -0
  26. package/src/cache/__tests__/intervalMapCache.test.ts +11 -0
  27. package/src/createAdaptedSelector.ts +9 -5
  28. package/src/createBoundSelector.ts +92 -84
  29. package/src/createCachedSequenceSelector.ts +12 -8
  30. package/src/createCachedStructuredSelector.ts +11 -20
  31. package/src/createChainSelector.ts +134 -89
  32. package/src/createPathSelector.ts +71 -104
  33. package/src/createPropSelector.ts +9 -8
  34. package/src/createSequenceSelector.ts +14 -9
  35. package/src/index.ts +2 -0
  36. package/src/keys/createKeySelectorComposer.ts +12 -23
  37. package/src/types.ts +115 -7
@@ -1,9 +1,14 @@
1
+ import { GetParamsFromSelectors, GetStateFromSelectors, Selector, SelectorResultArray, SelectorResultsMap, SelectorsObject, createSelector, createSelectorCreator } from "@veksa/reselect";
1
2
  import { ICacheObject, KeySelector, PolymorphicCachedOptions } from "@veksa/re-reselect";
2
- import { Selector, SelectorResultsMap, SelectorsObject, createSelectorCreator } from "@veksa/reselect";
3
3
  //#region src/createSegmentSelector.d.ts
4
4
  declare function createSegmentSelector<State, SelectedSegment extends State | State[keyof State]>(fn: (state: State) => SelectedSegment, initial: SelectedSegment): (state: State) => SelectedSegment;
5
5
  //#endregion
6
6
  //#region src/types.d.ts
7
+ /**
8
+ * The loosest shape a selector can take: a function of `state` plus any number
9
+ * of extra arguments. Used as the constraint for variadic tuple inference.
10
+ */
11
+ type AnySelector = (state: any, ...params: any[]) => any;
7
12
  /**
8
13
  * A selector carrying optional debug metadata. In the unified model a
9
14
  * "parametric" selector is simply a selector whose `Params` tuple is non-empty,
@@ -16,11 +21,6 @@ type NamedSelector<S, R, Params extends readonly any[] = [], D = unknown[]> = Se
16
21
  selectorName?: string;
17
22
  dependencies?: D;
18
23
  };
19
- /**
20
- * Back-compat alias: a parametric selector is a {@link NamedSelector} whose
21
- * single extra argument is `Props`.
22
- */
23
- type NamedParametricSelector<S, P, R, D = unknown[]> = NamedSelector<S, R, [P], D>;
24
24
  type Path = string[];
25
25
  /**
26
26
  * Turns a union `A | B | C` into the intersection `A & B & C`. Not exported by
@@ -28,54 +28,108 @@ type Path = string[];
28
28
  * intersect the `state`/`props` of several selectors.
29
29
  */
30
30
  type UnionToIntersection<Union> = (Union extends unknown ? (distributed: Union) => void : never) extends ((merged: infer Intersection) => void) ? Intersection : never;
31
+ /** The values of a group of selectors, whether it is an object or a tuple. */
32
+ type SelectorsUnion<Selectors> = Selectors extends readonly AnySelector[] ? Selectors[number] : Selectors[keyof Selectors];
33
+ /**
34
+ * The `state` argument of each selector in a union of them. Distributed over
35
+ * the union rather than matched against it, so each member is read on its own.
36
+ */
37
+ type StateOf<S> = S extends AnySelector ? Parameters<S>[0] : never;
38
+ /**
39
+ * The `props` argument of the selectors in a union that require one, or `never`
40
+ * for the ones that take none. The argument tuple is matched rather than the
41
+ * signature: a selector of `state` alone is assignable to one that also takes
42
+ * `props`, and would otherwise contribute `unknown`.
43
+ */
44
+ type RequiredPropsOf<S> = S extends AnySelector ? Parameters<S> extends [any, infer Props, ...any[]] ? Props : never : never;
45
+ /**
46
+ * The `props` argument of the selectors in a union that accept one without
47
+ * requiring it. An optional argument does not match the tuple pattern above,
48
+ * which is why it needs a pattern of its own; `undefined` is what the optional
49
+ * marker contributes and is dropped, so that intersecting the props of the
50
+ * group does not collapse to `never`.
51
+ *
52
+ * A selector that leaves its arguments open — `Selector<State, Result>` is
53
+ * `(state, ...args: any[]) => Result` — declares no props at all and must
54
+ * contribute nothing, or its `any` would swallow the props of every other
55
+ * selector in the group. It is told apart by the length of what follows
56
+ * `state`: an optional argument gives a finite `0 | 1`, a rest gives `number`.
57
+ */
58
+ type OptionalPropsOf<S> = S extends AnySelector ? Parameters<S> extends [any, any, ...any[]] ? never : Parameters<S> extends [any, ...infer Rest] ? number extends Rest['length'] ? never : Rest extends readonly [] ? never : Exclude<Rest[0], undefined> : never : never;
59
+ /**
60
+ * The `state` every selector in the group accepts: the intersection of their
61
+ * first arguments. An empty group constrains nothing, so it reads `unknown`
62
+ * rather than the `never` an intersection of no members would otherwise give.
63
+ */
64
+ type MergedState<Selectors> = Selectors extends readonly [] ? unknown : Selectors extends readonly AnySelector[] ? GetStateFromSelectors<Selectors> : UnionToIntersection<StateOf<SelectorsUnion<Selectors>>>;
65
+ /**
66
+ * The props of a union of selectors, as the argument tuple that reads all of
67
+ * them: empty when none takes props, optional when every selector that takes
68
+ * them declares them optional, required as soon as one selector requires them.
69
+ * The props themselves are intersected, so the argument satisfies each member.
70
+ */
71
+ type UnionProps<Union, Required = RequiredPropsOf<Union>, Optional = OptionalPropsOf<Union>> = [Required] extends [never] ? [Optional] extends [never] ? [] : [props?: UnionToIntersection<Optional>] : [props: UnionToIntersection<Required | Optional>];
72
+ /**
73
+ * The extra arguments the group takes beyond `state`: `[]` when no selector is
74
+ * parametric, `[Props]` when some are — with the `Props` of every parametric
75
+ * selector intersected.
76
+ *
77
+ * A tuple of selectors is merged position by position, so a selector taking
78
+ * more than `props` keeps its later arguments. An object is merged through the
79
+ * union of its values instead, which stops at `props` but costs nothing per
80
+ * key: the keys carry no order worth recovering, and a batch of selectors has
81
+ * no reason to be capped at a size a component could plausibly reach.
82
+ */
83
+ type MergedParams<Selectors> = Selectors extends readonly AnySelector[] ? GetParamsFromSelectors<Selectors> : UnionProps<SelectorsUnion<Selectors>>;
84
+ /**
85
+ * The same element-wise merge as {@link MergedParams}, for two argument tuples
86
+ * that are already known — the case of a step-by-step composition, where each
87
+ * step adds its own arguments to what the previous steps require.
88
+ */
89
+ type MergeParams<A extends readonly any[], B extends readonly any[]> = A extends readonly [] ? B : B extends readonly [] ? A : A extends readonly [infer AHead, ...infer ATail] ? B extends readonly [infer BHead, ...infer BTail] ? [AHead & BHead, ...MergeParams<ATail, BTail>] : A : B;
31
90
  //#endregion
32
91
  //#region src/createPathSelector.d.ts
33
92
  type Defined<T> = Exclude<T, undefined>;
34
93
  type IsOptional<T> = undefined extends T ? true : null extends T ? true : false;
35
94
  type IsObject<T> = T extends object ? true : false;
36
- type PathSelector<S, R, D> = NamedSelector<S, R, [], D> & {
37
- path: Path;
38
- };
39
- type PathParametricSelector<S, P, R, D> = NamedParametricSelector<S, P, R, D> & {
95
+ /**
96
+ * The selector a path builder produces. `Params` is carried through untouched
97
+ * from the base selector: walking a path changes the result, never the
98
+ * arguments, so the plain and the parametric case are the same type.
99
+ */
100
+ type PathSelector<S, R, Params extends readonly any[], D> = NamedSelector<S, R, Params, D> & {
40
101
  path: Path;
41
102
  };
42
103
  type Required<T> = { [P in keyof T]-?: Exclude<T[P], undefined | null>; };
43
- type RequiredSelectorBuilder<S, R, D> = R extends object ? { [K in keyof R]: () => PathSelector<S, NonNullable<R[K]>, D>; } : {};
44
- type OptionalSelectorBuilder<S, R, D> = ((defaultValue?: R) => PathSelector<S, R extends undefined ? Defined<R> : R, D>) & (R extends object ? { [K in keyof Required<R>]: () => PathSelector<S, NonNullable<R[K]>, D>; } : {});
45
- type RequiredParametricSelectorBuilder<S, P, R, D> = R extends object ? { [K in keyof R]: () => PathParametricSelector<S, P, NonNullable<R[K]>, D>; } : {};
46
- type OptionalParametricSelectorBuilder<S, P, R, D> = ((defaultValue?: R) => PathParametricSelector<S, P, R extends undefined ? Defined<R> : R, D>) & (R extends object ? { [K in keyof Required<R>]: () => PathParametricSelector<S, P, NonNullable<R[K]>, D>; } : {});
47
- type RequiredObjectSelectorWrapper<S, R, D> = { [K in keyof R]-?: IsOptional<R[K]> extends true ? OptionalPathSelectorType<S, R[K], D> : RequiredPathSelectorType<S, R[K], D>; };
48
- type OptionalObjectSelectorWrapper<S, R, D> = { [K in keyof R]-?: OptionalPathSelectorType<S, R[K], D>; };
49
- type RequiredObjectParametricSelectorWrapper<S, P, R, D> = { [K in keyof R]-?: IsOptional<R[K]> extends true ? OptionalPathParametricSelectorType<S, P, R[K], D> : RequiredPathParametricSelectorType<S, P, R[K], D>; };
50
- type OptionalObjectParametricSelectorWrapper<S, P, R, D> = { [K in keyof R]-?: OptionalPathParametricSelectorType<S, P, R[K], D>; };
51
- type RequiredArraySelectorWrapper<S, R, D> = {
52
- length: RequiredPathSelectorType<S, number, D>;
53
- [K: number]: IsOptional<R> extends true ? OptionalPathSelectorType<S, R, D> : RequiredPathSelectorType<S, R, D>;
54
- };
55
- type OptionalArraySelectorWrapper<S, R, D> = {
56
- length: RequiredPathSelectorType<S, number, D>;
57
- [K: number]: OptionalPathSelectorType<S, R, D>;
58
- };
59
- type RequiredArrayParametricSelectorWrapper<S, P, R, D> = {
60
- length: RequiredPathParametricSelectorType<S, P, number, D>;
61
- [K: number]: IsOptional<R> extends true ? OptionalPathParametricSelectorType<S, P, R, D> : RequiredPathParametricSelectorType<S, P, R, D>;
104
+ type RequiredSelectorBuilder<S, R, Params extends readonly any[], D> = R extends object ? { [K in keyof R]: () => PathSelector<S, NonNullable<R[K]>, Params, D>; } : {};
105
+ type OptionalSelectorBuilder<S, R, Params extends readonly any[], D> = ((defaultValue?: R) => PathSelector<S, R extends undefined ? Defined<R> : R, Params, D>) & (R extends object ? { [K in keyof Required<R>]: () => PathSelector<S, NonNullable<R[K]>, Params, D>; } : {});
106
+ type RequiredObjectSelectorWrapper<S, R, Params extends readonly any[], D> = { [K in keyof R]-?: IsOptional<R[K]> extends true ? OptionalPathSelectorType<S, R[K], Params, D> : RequiredPathSelectorType<S, R[K], Params, D>; };
107
+ type OptionalObjectSelectorWrapper<S, R, Params extends readonly any[], D> = { [K in keyof R]-?: OptionalPathSelectorType<S, R[K], Params, D>; };
108
+ type RequiredArraySelectorWrapper<S, R, Params extends readonly any[], D> = {
109
+ length: RequiredPathSelectorType<S, number, Params, D>;
110
+ [K: number]: IsOptional<R> extends true ? OptionalPathSelectorType<S, R, Params, D> : RequiredPathSelectorType<S, R, Params, D>;
62
111
  };
63
- type OptionalArrayParametricSelectorWrapper<S, P, R, D> = {
64
- length: RequiredPathParametricSelectorType<S, P, number, D>;
65
- [K: number]: OptionalPathParametricSelectorType<S, P, R, D>;
112
+ type OptionalArraySelectorWrapper<S, R, Params extends readonly any[], D> = {
113
+ length: RequiredPathSelectorType<S, number, Params, D>;
114
+ [K: number]: OptionalPathSelectorType<S, R, Params, D>;
66
115
  };
67
- type RequiredDataSelectorWrapper<S, R, D> = R extends unknown[] ? RequiredArraySelectorWrapper<S, R[number], D> : IsObject<R> extends true ? RequiredObjectSelectorWrapper<S, R, D> : RequiredSelectorBuilder<S, R, D>;
68
- type OptionalDataSelectorWrapper<S, R, D> = R extends unknown[] ? OptionalArraySelectorWrapper<S, R[number], D> : IsObject<R> extends true ? OptionalObjectSelectorWrapper<S, R, D> : OptionalSelectorBuilder<S, R, D>;
69
- type RequiredDataParametricSelectorWrapper<S, P, R, D> = R extends unknown[] ? RequiredArrayParametricSelectorWrapper<S, P, R[number], D> : IsObject<R> extends true ? RequiredObjectParametricSelectorWrapper<S, P, R, D> : RequiredParametricSelectorBuilder<S, P, R, D>;
70
- type OptionalDataParametricSelectorWrapper<S, P, R, D> = R extends unknown[] ? OptionalArrayParametricSelectorWrapper<S, P, R[number], D> : IsObject<R> extends true ? OptionalObjectParametricSelectorWrapper<S, P, R, D> : OptionalParametricSelectorBuilder<S, P, R, D>;
71
- type RequiredPathSelectorType<S, R, D> = RequiredSelectorBuilder<S, R, D> & RequiredDataSelectorWrapper<S, NonNullable<R>, D>;
72
- type OptionalPathSelectorType<S, R, D> = OptionalSelectorBuilder<S, R, D> & OptionalDataSelectorWrapper<S, NonNullable<R>, D>;
73
- type RequiredPathParametricSelectorType<S, P, R, D> = RequiredParametricSelectorBuilder<S, P, R, D> & RequiredDataParametricSelectorWrapper<S, P, NonNullable<R>, D>;
74
- type OptionalPathParametricSelectorType<S, P, R, D> = OptionalParametricSelectorBuilder<S, P, R, D> & OptionalDataParametricSelectorWrapper<S, P, NonNullable<R>, D>;
75
- declare function createPathSelector<S, R, P = void>(baseSelector: P extends void ? Selector<S, R> : Selector<S, R, [P]>): P extends void ? IsOptional<R> extends true ? OptionalPathSelectorType<S, R, [Selector<S, R>]> : RequiredPathSelectorType<S, R, [Selector<S, R>]> : IsOptional<R> extends true ? OptionalPathParametricSelectorType<S, P, R, [Selector<S, R, [P]>]> : RequiredPathParametricSelectorType<S, P, R, [Selector<S, R, [P]>]>;
116
+ type RequiredDataSelectorWrapper<S, R, Params extends readonly any[], D> = R extends unknown[] ? RequiredArraySelectorWrapper<S, R[number], Params, D> : IsObject<R> extends true ? RequiredObjectSelectorWrapper<S, R, Params, D> : RequiredSelectorBuilder<S, R, Params, D>;
117
+ type OptionalDataSelectorWrapper<S, R, Params extends readonly any[], D> = R extends unknown[] ? OptionalArraySelectorWrapper<S, R[number], Params, D> : IsObject<R> extends true ? OptionalObjectSelectorWrapper<S, R, Params, D> : OptionalSelectorBuilder<S, R, Params, D>;
118
+ type RequiredPathSelectorType<S, R, Params extends readonly any[], D> = RequiredSelectorBuilder<S, R, Params, D> & RequiredDataSelectorWrapper<S, NonNullable<R>, Params, D>;
119
+ type OptionalPathSelectorType<S, R, Params extends readonly any[], D> = OptionalSelectorBuilder<S, R, Params, D> & OptionalDataSelectorWrapper<S, NonNullable<R>, Params, D>;
120
+ /**
121
+ * Builds a proxy that turns property access into a selector reading that path.
122
+ *
123
+ * `Params` is inferred straight from the base selector, so the plain and the
124
+ * parametric case share one signature — and one set of builder types — instead
125
+ * of being told apart by a conditional in the parameter position. It defaults
126
+ * to empty so that `createPathSelector<State, Result>(selector)` keeps working
127
+ * for callers that spell the type arguments out.
128
+ */
129
+ declare function createPathSelector<S, R, Params extends readonly any[] = []>(baseSelector: (state: S, ...params: Params) => R): IsOptional<R> extends true ? OptionalPathSelectorType<S, R, Params, [typeof baseSelector]> : RequiredPathSelectorType<S, R, Params, [typeof baseSelector]>;
76
130
  //#endregion
77
131
  //#region src/createPropSelector.d.ts
78
- declare function createPropSelector<P>(): RequiredPathParametricSelectorType<unknown, P, P, [Selector<unknown, P, [P]>]>;
132
+ declare function createPropSelector<P>(): RequiredPathSelectorType<unknown, P, [P], [Selector<unknown, P, [P]>]>;
79
133
  //#endregion
80
134
  //#region src/keys/createKeySelectorComposer.d.ts
81
135
  /**
@@ -83,38 +137,38 @@ declare function createPropSelector<P>(): RequiredPathParametricSelectorType<unk
83
137
  * number of extra arguments (props, ...). Used for variadic tuple inference.
84
138
  */
85
139
  type AnyKeySelector = KeySelector<any>;
86
- /** Intersection of every input key selector's `state` argument. */
87
- type ComposedState<Ks extends readonly AnyKeySelector[]> = UnionToIntersection<{ [Index in keyof Ks]: Parameters<Ks[Index]>[0]; }[number]>;
88
- /** Union of every input key selector's `props` argument (position 1), if any. */
89
- type PropsUnion<Ks extends readonly AnyKeySelector[]> = { [Index in keyof Ks]: Parameters<Ks[Index]> extends [any, infer Props, ...any[]] ? Props : never; }[number];
90
- /** Intersection of every input key selector's `props`, or `never` if none are parametric. */
91
- type ComposedProps<Ks extends readonly AnyKeySelector[]> = [PropsUnion<Ks>] extends [never] ? never : UnionToIntersection<PropsUnion<Ks>>;
92
140
  /**
93
141
  * The key selector produced by a {@link KeySelectorComposer}: a function that
94
- * intersects the `state` (and `props`, when any input is parametric) of every
95
- * composed key selector, tagged with the original inputs as `dependencies`.
142
+ * intersects the `state` and the extra arguments of every composed key
143
+ * selector, tagged with the original inputs as `dependencies`.
96
144
  */
97
- type OutputKeySelector<S, P, D extends readonly AnyKeySelector[]> = ([P] extends [never] ? (state: S) => unknown : (state: S, props: P) => unknown) & {
145
+ type OutputKeySelector<S, Params extends readonly any[], D extends readonly AnyKeySelector[]> = ((state: S, ...params: Params) => unknown) & {
98
146
  dependencies: D;
99
147
  };
100
148
  /**
101
149
  * Composes N key selectors into a single one. A single variadic signature with
102
- * tuple inference replaces the former per-arity overload set.
150
+ * tuple inference replaces the former per-arity overload set; `state` and the
151
+ * extra arguments are merged by the same helpers every other multi-selector
152
+ * creator in the library uses.
103
153
  */
104
- type KeySelectorComposer = <Ks extends readonly AnyKeySelector[]>(...keySelectors: Ks) => OutputKeySelector<ComposedState<Ks>, ComposedProps<Ks>, Ks>;
154
+ type KeySelectorComposer = <Ks extends readonly AnyKeySelector[]>(...keySelectors: Ks) => OutputKeySelector<MergedState<Ks>, MergedParams<Ks>, Ks>;
105
155
  declare function createKeySelectorComposer(baseKeySelectorComposer: (...keySelectors: AnyKeySelector[]) => AnyKeySelector): KeySelectorComposer;
106
156
  //#endregion
107
157
  //#region src/createBoundSelector.d.ts
108
158
  /**
109
- * The special type to prevent binding of non optional props on optional values
159
+ * The bound selector: what the binding did not supply is what is left to pass.
160
+ * A binding covering every prop leaves an empty argument tuple, which is what a
161
+ * plain selector is in the unified model — so one type covers both cases.
162
+ *
163
+ * The outer condition is the guard against binding a prop the base selector
164
+ * declares as optional with a value that is not.
110
165
  */
111
- type BoundSelector<S, P2, P1 extends Partial<P2>, R> = P2 extends Pick<P1, keyof P2> ? Exclude<keyof P1, keyof P2> extends never ? NamedSelector<S, R> : NamedParametricSelector<S, Omit<P1, keyof P2>, R> : never;
166
+ type BoundSelector<S, P2, P1 extends Partial<P2>, R> = P2 extends Pick<P1, keyof P2> ? NamedSelector<S, R, Exclude<keyof P1, keyof P2> extends never ? [] : [Omit<P1, keyof P2>]> : never;
112
167
  type BoundSelectorOptions<S, P2, P1 extends Partial<P2>, R> = {
113
- bindingStrategy?: (baseSelector: Selector<S, R, [P1]>, binding: P2) => Selector<S, R, [Omit<P1, keyof P2>]>;
168
+ bindingStrategy?: (baseSelector: (state: S, props: P1) => R, binding: P2) => (state: S, props: Omit<P1, keyof P2>) => R;
114
169
  keySelectorComposer?: KeySelectorComposer;
115
170
  };
116
- declare const createBoundInnerSelector: <S, P2 extends object, P1 extends Partial<P2>, R, OR extends R>(baseSelector: Selector<S, R, [P1]>, binding: P2, options?: BoundSelectorOptions<S, P2, P1, OR>) => BoundSelector<S, P2, P1, R>;
117
- declare const createBoundSelector: typeof createBoundInnerSelector;
171
+ declare const createBoundSelector: <S, P2 extends object, P1 extends Partial<P2>, R, OR extends R>(baseSelector: (state: S, props: P1) => R, binding: P2, options?: BoundSelectorOptions<S, P2, P1, OR>) => BoundSelector<S, P2, P1, R>;
118
172
  //#endregion
119
173
  //#region src/createEmptySelector.d.ts
120
174
  /**
@@ -131,15 +185,21 @@ declare const createBoundSelector: typeof createBoundInnerSelector;
131
185
  declare const createEmptySelector: <S, R>(baseSelector: Selector<S, R, any[]>) => Selector<S, R | undefined>;
132
186
  //#endregion
133
187
  //#region src/createAdaptedSelector.d.ts
134
- declare const createAdaptedSelector: <S, P1 extends object, P2, R>(baseSelector: Selector<S, R, [P1]>, mapping: (props: P2) => P1) => NamedParametricSelector<S, P2, R>;
188
+ /**
189
+ * Rewrites the props a selector reads. Only the props argument changes: the
190
+ * adapted selector takes `[P2]` where the base took `[P1]`, which is the same
191
+ * argument tuple every other creator in the library carries.
192
+ */
193
+ declare const createAdaptedSelector: <S, P1 extends object, P2, R>(baseSelector: (state: S, props: P1) => R, mapping: (props: P2) => P1) => NamedSelector<S, R, [P2]>;
135
194
  //#endregion
136
195
  //#region src/createChainSelector.d.ts
137
- type SelectorChain<R1, S1, R2> = (result: R1) => Selector<S1, R2>;
138
- type ParametricSelectorChain<R1, S1, P1, R2> = (result: R1) => Selector<S1, R2, [P1]>;
139
- type SelectorChainHierarchy<C extends SelectorChain<any, any, any>, H extends SelectorChainHierarchy<any, any>> = C & {
140
- parentChain?: H;
141
- };
142
- type ParametricSelectorChainHierarchy<C extends ParametricSelectorChain<any, any, any, any>, H extends ParametricSelectorChainHierarchy<any, any>> = C & {
196
+ /**
197
+ * A chain step: given the previous level's result, it returns the selector the
198
+ * next level reads. `Params` is empty for a step that only needs `state`, so a
199
+ * single type covers what used to be a plain and a parametric variant.
200
+ */
201
+ type SelectorChain<R1, S1, R2, Params extends readonly any[] = []> = (result: R1) => Selector<S1, R2, Params>;
202
+ type SelectorChainHierarchy<C extends SelectorChain<any, any, any, any>, H extends SelectorChainHierarchy<any, any>> = C & {
143
203
  parentChain?: H;
144
204
  };
145
205
  type CreateSelectorOptions<SelectorCreator extends typeof createSelectorCreator> = {
@@ -150,42 +210,60 @@ type ChainSelectorOptions<SelectorCreator extends typeof createSelectorCreator =
150
210
  createSelectorOptions?: () => CreateSelectorOptions<SelectorCreator>;
151
211
  keySelectorComposer?: KeySelectorComposer;
152
212
  };
153
- interface ChainSelectorResult<S1, R1> {
154
- chain: <S2, R2 = any>(fn: SelectorChain<R1, S2, R2>, chainOptions?: ChainSelectorOptions) => ChainSelectorResult<S1 & S2, R2>;
155
- map: <R2>(fn: (result: R1) => R2, mapOptions?: ChainSelectorOptions) => ChainSelectorResult<S1, R2>;
156
- build: () => Selector<S1, R1, []> & {
213
+ /**
214
+ * Every level of the chain carries the arguments its selector needs. A level
215
+ * that only reads `state` leaves `Params` empty, and one that reads props adds
216
+ * them — so a step introducing props makes them required for the whole built
217
+ * selector, whether or not the base selector had any.
218
+ *
219
+ * `Params` defaults to empty on the entry point, so that
220
+ * `createChainSelector<State, Result>(selector)` keeps working for callers that
221
+ * spell the type arguments out.
222
+ */
223
+ interface ChainSelectorResult<S1, R1, Params extends readonly any[]> {
224
+ chain: <S2, R2, Params2 extends readonly any[]>(fn: (result: R1) => (state: S2, ...params: Params2) => R2, chainOptions?: ChainSelectorOptions) => ChainSelectorResult<S1 & S2, R2, MergeParams<Params, Params2>>;
225
+ map: <R2>(fn: (result: R1) => R2, mapOptions?: ChainSelectorOptions) => ChainSelectorResult<S1, R2, Params>;
226
+ build: () => Selector<S1, R1, Params> & {
157
227
  chainHierarchy: SelectorChainHierarchy<any, any> | undefined;
158
228
  };
159
229
  }
160
- interface ParametricChainSelectorResult<S1, P1, R1> {
161
- chain: <S2, P2 = unknown, R2 = any>(fn: ParametricSelectorChain<R1, S2, P2, R2>, chainOptions?: ChainSelectorOptions) => ParametricChainSelectorResult<S1 & S2, P1 & P2, R2>;
162
- map: <R2>(fn: (result: R1) => R2, mapOptions?: ChainSelectorOptions) => ParametricChainSelectorResult<S1, P1, R2>;
163
- build: () => Selector<S1, R1, [P1]> & {
164
- chainHierarchy: ParametricSelectorChainHierarchy<any, any> | undefined;
165
- };
166
- }
167
- declare function createChainSelector<S1, R1>(selector: Selector<S1, R1>, options?: ChainSelectorOptions, prevChain?: SelectorChainHierarchy<any, any>): ChainSelectorResult<S1, R1>;
168
- declare function createChainSelector<S1, P1, R1>(selector: Selector<S1, R1, [P1]>, options?: ChainSelectorOptions, prevChain?: ParametricSelectorChainHierarchy<any, any>): ParametricChainSelectorResult<S1, P1, R1>;
230
+ declare function createChainSelector<S1, R1, Params extends readonly any[] = []>(selector: (state: S1, ...params: Params) => R1, options?: ChainSelectorOptions, prevChain?: SelectorChainHierarchy<any, any>): ChainSelectorResult<S1, R1, Params>;
231
+ //#endregion
232
+ //#region src/createSequenceSelector.d.ts
233
+ /**
234
+ * Runs a group of selectors and collects their results positionally.
235
+ *
236
+ * The selectors are inferred as a tuple rather than an array, which is what
237
+ * makes the result a tuple of the individual result types and lets `state` and
238
+ * the extra arguments be merged per position. An array would collapse them into
239
+ * a union and resolve everything past `state` to `never`, which is why the
240
+ * plain and the parametric case used to need an overload each.
241
+ */
242
+ declare function createSequenceSelector<Selectors extends readonly AnySelector[]>(selectors: [...Selectors], selectorCreator?: typeof createSelector): Selector<MergedState<Selectors>, SelectorResultArray<Selectors>, MergedParams<Selectors>>;
169
243
  //#endregion
170
244
  //#region src/createCachedSequenceSelector.d.ts
171
- declare function createCachedSequenceSelector<S, R>(selectors: Selector<S, R>[]): (options: PolymorphicCachedOptions<Selector<S, R>[], R[]>) => Selector<S, R[]>;
172
- declare function createCachedSequenceSelector<S, P, R>(selectors: Selector<S, R, [P]>[]): (options: PolymorphicCachedOptions<Selector<S, R, [P]>[], R[]>) => Selector<S, R[], [P]>;
245
+ /**
246
+ * The cached counterpart of {@link createSequenceSelector}. The inferred tuple
247
+ * reaches `PolymorphicCachedOptions` as-is, so re-reselect types the caller's
248
+ * `keySelector` with the exact arguments of the group.
249
+ */
250
+ declare function createCachedSequenceSelector<Selectors extends readonly AnySelector[]>(selectors: [...Selectors]): (options: PolymorphicCachedOptions<Selectors, SelectorResultArray<Selectors>>) => Selector<MergedState<Selectors>, SelectorResultArray<Selectors>, MergedParams<Selectors>>;
173
251
  //#endregion
174
252
  //#region src/createCachedStructuredSelector.d.ts
175
- /** Intersection of the `state` argument of every selector in the object. */
176
- type StructuredState<M extends SelectorsObject> = UnionToIntersection<{ [K in keyof M]: Parameters<M[K]>[0]; }[keyof M]>;
177
- /** Union of the `props` argument (position 1) of every parametric selector. */
178
- type StructuredPropsUnion<M extends SelectorsObject> = { [K in keyof M]: Parameters<M[K]> extends [any, infer Props, ...any[]] ? Props : never; }[keyof M];
179
- /** The extra-arguments tuple: `[Props]` when any selector is parametric, else `[]`. */
180
- type StructuredParams<M extends SelectorsObject> = [StructuredPropsUnion<M>] extends [never] ? [] : [UnionToIntersection<StructuredPropsUnion<M>>];
181
- /** The input selectors as reselect sees them, used to type the cached options. */
182
- type StructuredInputs<M extends SelectorsObject> = Selector<StructuredState<M>, unknown, StructuredParams<M>>[];
253
+ /**
254
+ * The input selectors as re-reselect reads them when typing the caller's
255
+ * `keySelector`: it takes `state` and the extra arguments off the group, and
256
+ * both are already merged here. Putting the selectors back in key order would
257
+ * type the arguments no more precisely and would cost a type instantiation per
258
+ * key, capping the batch at roughly fifty fields.
259
+ */
260
+ type StructuredInputs<M extends SelectorsObject> = Selector<MergedState<M>, unknown, MergedParams<M>>[];
183
261
  /**
184
262
  * A single variadic signature replaces the former `Selector` / `ParametricSelector`
185
263
  * conditional: `state` and `props` are derived from the selectors object, so a
186
264
  * parametric input keeps its props type without a separate overload.
187
265
  */
188
- declare function createCachedStructuredSelector<M extends SelectorsObject>(selectors: M): (options: PolymorphicCachedOptions<StructuredInputs<M>, SelectorResultsMap<M>>) => Selector<StructuredState<M>, SelectorResultsMap<M>, StructuredParams<M>>;
266
+ declare function createCachedStructuredSelector<M extends SelectorsObject>(selectors: M): (options: PolymorphicCachedOptions<StructuredInputs<M>, SelectorResultsMap<M>>) => Selector<MergedState<M>, SelectorResultsMap<M>, MergedParams<M>>;
189
267
  //#endregion
190
268
  //#region src/keys/defaultKeySelector.d.ts
191
269
  declare const defaultKeySelector: () => string;
@@ -241,8 +319,39 @@ declare class TreeCache implements ICacheObject {
241
319
  }
242
320
  //#endregion
243
321
  //#region src/_hooks/useSelector.d.ts
244
- declare function useSelector<S extends object, R>(selector: (state: S) => R): R;
245
- declare function useSelector<S extends object, P, R>(selector: (state: S, props: P) => R, props: P): R;
322
+ /**
323
+ * Reads one selector from the store. Props are compared shallowly, so an inline
324
+ * object literal does not invalidate the selector on every render.
325
+ *
326
+ * A single variadic signature covers both the plain and the parametric case:
327
+ * `Params` is inferred from the selector itself and is empty when the selector
328
+ * takes nothing but `state`, so the props argument is required exactly when the
329
+ * selector declares one. `NoInfer` keeps the props argument out of that
330
+ * inference -- otherwise an inline object literal would widen `Params` instead
331
+ * of being checked against what the selector declares. It defaults to empty so
332
+ * that `useSelector<State, Result>(selector)` -- the call site of the former
333
+ * plain overload -- keeps compiling without spelling the tuple out.
334
+ *
335
+ * Use {@link useSelectors} to read several selectors through a single store
336
+ * subscription.
337
+ */
338
+ declare function useSelector<S extends object, R, Params extends readonly any[] = []>(selector: (state: S, ...params: Params) => R, ...params: NoInfer<Params>): R;
339
+ //#endregion
340
+ //#region src/_hooks/useSelectors.d.ts
341
+ /**
342
+ * Reads a batch of selectors through a single store subscription and returns
343
+ * their results as one object.
344
+ *
345
+ * Seven `useSelector` calls in a row component mean seven store listeners,
346
+ * seven `useSyncExternalStore` instances and seven snapshot comparisons per
347
+ * dispatch. This collapses them into one of each; the trade-off is that any
348
+ * tracked state segment changing re-runs the whole batch, which for memoized
349
+ * selectors is a cache hit per field.
350
+ *
351
+ * The memoization lives in the component instance, so rows do not compete for
352
+ * a shared cache the way a module-level structured selector would.
353
+ */
354
+ declare function useSelectors<M extends SelectorsObject>(selectors: M, ...params: MergedParams<M>): SelectorResultsMap<M>;
246
355
  //#endregion
247
- export { type ChainSelectorOptions, IntervalMapCache, TreeCache, arrayComposeKeySelectors, createAdaptedSelector, createBoundSelector, createCachedSequenceSelector, createCachedStructuredSelector, createChainSelector, createEmptySelector, createKeySelectorComposer, createKeySelectorCreator, createPathSelector, createPropSelector, createSegmentSelector, defaultKeySelector, initGarbageCollector, isDebugMode, setDebugMode, stringComposeKeySelectors, useSelector };
356
+ export { type ChainSelectorOptions, IntervalMapCache, TreeCache, arrayComposeKeySelectors, createAdaptedSelector, createBoundSelector, createCachedSequenceSelector, createCachedStructuredSelector, createChainSelector, createEmptySelector, createKeySelectorComposer, createKeySelectorCreator, createPathSelector, createPropSelector, createSegmentSelector, createSequenceSelector, defaultKeySelector, initGarbageCollector, isDebugMode, setDebugMode, stringComposeKeySelectors, useSelector, useSelectors };
248
357
  //# sourceMappingURL=reselectKit.d.ts.map