Skip to content

Commit

Permalink
Expose lastResult util to aid in ad-hoc caching
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson committed Oct 20, 2021
1 parent f38c8d5 commit c9a5207
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export function createSelectorCreator<
// (memoize: MemoizeFunction, ...memoizeOptions: MemoizerOptions) {
const createSelector = (...funcs: Function[]) => {
let recomputations = 0
let lastResult: unknown

// Due to the intricacies of rest params, we can't do an optional arg after `...funcs`.
// So, start by declaring the default value here.
Expand Down Expand Up @@ -121,12 +122,14 @@ export function createSelectorCreator<
}

// apply arguments instead of spreading for performance.
return memoizedResultFunc.apply(null, params)
lastResult = memoizedResultFunc.apply(null, params)
return lastResult
})

selector.resultFunc = resultFunc
selector.memoizedResultFunc = memoizedResultFunc
selector.dependencies = dependencies
selector.lastResult = () => lastResult
selector.recomputations = () => recomputations
selector.resetRecomputations = () => (recomputations = 0)
return selector
Expand Down
16 changes: 11 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ export type Selector<
P extends never | readonly any[] = any[]
> = [P] extends [never] ? (state: S) => R : (state: S, ...params: P) => R

interface OutputSelectorFields<Combiner> {
interface OutputSelectorFields<Combiner, Result> {
resultFunc: Combiner
memoizedResultFunc: Combiner
lastResult: () => Result
dependencies: SelectorArray
recomputations: () => number
resetRecomputations: () => number
Expand All @@ -18,12 +19,17 @@ export type OutputSelector<
Params extends readonly any[],
Combiner
> = Selector<GetStateFromSelectors<S>, Result, Params> &
OutputSelectorFields<Combiner>
OutputSelectorFields<Combiner, Result>

export type ParametricSelector<S, P, R> = Selector<S, R, [P, ...any]>
export type ParametricSelector<State, Props, Result> = Selector<
State,
Result,
[Props, ...any]
>

export type OutputParametricSelector<S, P, R, C> = ParametricSelector<S, P, R> &
OutputSelectorFields<C>
export type OutputParametricSelector<State, Props, Result, Combiner> =
ParametricSelector<State, Props, Result> &
OutputSelectorFields<Combiner, Result>

export type SelectorArray = ReadonlyArray<Selector>

Expand Down
12 changes: 12 additions & 0 deletions test/test_selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -730,4 +730,16 @@ describe('createSelector exposed utils', () => {
const selector = createSelector(dependency1, dependency2, () => {})
expect(selector.dependencies).toEqual([dependency1, dependency2])
})

test('export lastResult function', () => {
const selector = createSelector(
(state: StateAB) => state.a,
(state: StateAB) => state.b,
(a, b) => a + b
)

const result = selector({ a: 1, b: 2 })
expect(result).toBe(3)
expect(selector.lastResult()).toBe(3)
})
})

0 comments on commit c9a5207

Please sign in to comment.