v4.1.0 #524
markerikson
started this conversation in
General
v4.1.0
#524
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
This long-overdue release updates
defaultMemoizeto accept new options for cache size > 1 and a result equality check, updatescreateSelectorto accept an options object containing options for the providedmemoizefunction, makes major improvements to the TypeScript types (targeting TS 4.2+), converts the codebase to TS, improves some error messages, and addsmemoizedResultFuncandlastResultto the fields attached to the selector,This should be a drop-in update - the only expected backwards compatibility issues are with incorrect or very outdated TypeScript usage patterns.
Changelog
New
defaultMemoizeOptionsdefaultMemoizehas always been fairly limited. Its signature was(func: Function, equalityCheck?: EqualityFn) => Function, and only ever had a cache size of 1. This has led to many annoyances and workarounds, typically involving callingcreateSelectorCreator()with a custom memoization function that has a larger cache size or more options for customizing comparisons.We've updated
defaultMemoizeto allow cache sizes > 1, as well as customize comparisons of the newly generated result value to improve cache hits.The signature for
defaultMemoizeis now:In other words, you can still pass
equalityCheckas its one additional arg, or you may pass an object containing several possible options.If the
maxSizevalue is greater than 1,defaultMemoizewill now use an LRU cache based on https://github.com/erikras/lru-memoize internally.If
resultEqualityCheckis provided, it will be used to compare the newly-generated value fromfuncagainst all other values in the cache, in LRU order. If a cached value is found to be equal, that value will be returned. This addresses the commontodos.map(todo => todo.id)use case, where a change to any field in anytodoobject creates a newtodosarray and thus causes the output to be recalculated, but the generated IDs array is still shallow-equal to the last result. You can now pass an equality function likeshallowEqualas theresultEqualityCheckargument, and it will reuse the old IDs array instead.createSelectorOptionsPreviously, the only way to customize behavior of
createSelectorwas to generate a customized version withcreateSelectorCreator. By far the most common use case was customizing theequalityCheckoption used withdefaultMemoize, or using a different memoizer entirely. This usually looked like:createSelectorCreatoralso accepted additional positional parameters, and forwarded all of them to the providedmemoizefunction, sodefaultMemoizeultimately gets called internally asdefaultMemoize(actualFunction, shallowEqual).This added an annoying level of indirection to common customization use cases.
createSelectornow accepts an options object as its last argument, after the output selector. Currently, that object only includes one field:memoizeOptions:Similar to how
createSelectorCreatoraccepts additional "options args" that get forwarded to the memoization function, thememoizeOptionsfield accepts an array of those "options args" as well. If provided, these override what was given tocreateSelectorCreator.That means that you can now customize memoization behavior with direct options to
createSelector. And, becausedefaultMemoizenow accepts more options, you can directly customizedefaultMemoize's behavior without usingcreateSelectorCreator.Additionally, because it's very common to only need to pass one options arg to the memoization function,
memoizeOptionsmay also be just that first options arg by itself, without any array.Example usages of this look like:
This should make it much easier to customize behavior.
All of this is fully TypeScript-typed, and the possible values for
memoizeOptionsshould be fully inferred from the providedmemoizefunction.Additionally,
defaultMemoizenow supports clearing the cache inside a memoized function (regardless of cache size). The memoized function returned fromdefaultMemoizewill now have a.clearCache()method attached that will clear the cache.When using
createSelector, this can be accessed usingselector.memoizedResultFunc.clearCache().TypeScript Improvements
The Reselect types were written several years ago and originally targeted TS 2.x versions. As a result, the typedefs requires dozens of overloads to handle varying numbers of arguments (see the legacy typedefs file for examples).
We've converted the codebase to be written in TypeScript, and as part of that process we've completely rewritten the TS typedefs to use modern TS syntax like mapped types. This drastically shrinks the size of the typedefs (from 1000 lines to about 115), and also improves the actual type inference overall. Assuming the input selectors are correctly and consistently typed, TS will now fully infer the return values of all input selectors, the arguments to the output selector, and the exact type of the memoized function.
The updated types do require use of TS 4.2+. We've attempted to keep the final public type names and usage the same, but there may also be some types breakage. We'd appreciate feedback on any meaningful breakage issues so we can make further tweaks if needed.
Given the intent of the improvements, that they're all type-only changes, the attempts to retain backwards compatibility, and TS's own versioning scheme, we're considering this to be a minor version change rather than a major.
In pre-release testing, the main issues we saw were:
statearg. Fix: explicitly add a type tostate<A, B, C, D>generics from thecreateSelector()call.The legacy types are still included, and should automatically be used if you are using TS 4.1 and earlier. Note that the legacy types do not include the definitions for the new
defaultMemoizeoptions - you'll need to be on TS 4.2+ to use those with TS.Additional Tweaks
We've improved the error messages thrown when invalid selectors are provided.
Generated selectors now include
selector.memoizedResultFuncandselector.lastResultfor later access if needed.Changes
The early alphas contained code from several outstanding PRs, pulled together:
memoizetype fixes ( @micahbales )createStructuredSelectorinference ( @oatkiller )Additional work included:
defaultMemoizeto accept options (maxSize, equalityCheck, resultEqualityCheck) by @markerikson in Update createSelector anddefaultMemoizeto accept options (maxSize, equalityCheck, resultEqualityCheck) #513clearCachemethod to defaultMemoize output functions by @markerikson in Add aclearCachemethod to defaultMemoize output functions #519Full Changelog: v4.0.0...v4.1.0
This discussion was created from the release v4.1.0.
Beta Was this translation helpful? Give feedback.
All reactions