Releases: alexreardon/memoize-one
5.0.0
New custom equality function api
Previously we could call a custom equality function for each argument. Now we call it once and pass in the complete sets of arguments. This allows for a lot more flexibility.
- type EqualityFn = (newValue: mixed, oldValue: mixed) => boolean;
+ type EqualityFn = (newArgs: mixed[], lastArgs: mixed[]) => boolean
Old behaviour
const memoized = memoizeOne(fn, isEqual);
memoized(1, 2);
// isEqual not called on first call
memoized(1, 3);
// isEqual called two times
// first call: (1, 1) (newArg, oldArg)
// second call: (3, 2) (newArg, oldArg)
New behaviour
const memoized = memoizeOne(fn, isEqual);
memoized(1, 2);
// isEqual not called on first call
memoized(1, 3);
// isEqual called one time
// first call: ([1, 3], [1, 2]) (newArgs, oldArgs)
We have provided a detailed usage guide
This resulted in a breaking change 💥. However, it will only impact you if you are using a custom equality function. Addtionally, some libraries such as
lodash.isequal
will handle this api change without you requiring to make any code changes.
Engineering health
- Moved to
flow
0.89
- Moved to
prettier
for formatting - More tests!
Thanks to the following people for their assistance with this release ❤️:
4.1.0
🛑This release has been deprecated
New feature: index
provided to equality function #42
🛑This feature has been removed and replaced with a new custom equality pattern
Thanks @nihgwu for submitting this one!
If you are not providing your own custom equality function then there nothing to see here 👍
Custom equality functions are now provided with a third argument: the index
of the argument.
-type EqualityFn = (newValue: mixed, oldValue: mixed) => boolean;
+type EqualityFn = (newValue: mixed, oldValue: mixed, index: number) => boolean;
This can be useful if you want to do different types of checking depending on the order of the argument.
import memoizeOne from 'memoize-one';
import deepEqual from 'lodash.isEqual';
const myEqualFn = (newArg, lastArg, index) => {
// use deep equal for first arg
if(index === 0) {
return deepEqual(newArg, lastArg);
}
// use shallow equal for all other arguments
return newArg === lastArg;
}
const fn = (...args) => {
console.log('called with', ...args);
};
const memoized = memoizeOne(fn, myEqualFn);
memoized({hello: 'world'}, 5);
// console.log('called with', {hello: 'world'}, 5);
memoized({hello: 'world'}, 5);
// no call to console.log
This resulted in a feature release
Engineering health
- Upgraded to
flow
0.88
- Upgraded all
flow-typed
lib definitions - Upgraded all dev dependencies
4.0.3
- Upgrading to
flow
0.85
- Upgrading dev deps
4.0.2
Improvements
Faster and less cache busts with throw
We are still gracefully handling result functions that throw
. We have made a few improvements:
- no longer using a
try / catch
for maximum performance - more details - calls to the result function that end up causing a
throw
will no longer break the memoization cache
Thanks @ChristopherChudzicki for originally pointing me in this direction
4.0.1
Fixes
Handling functions that throw
#31
Previously if your result function threw a value you could get some strange behaviour. We have fixed this so that memoizeOne
is aware when your result function throws a value. If your result function throws then the memoized function will also throw. A thrown value is not cached and the result function will be re-executed if called again with the same arguments.
const willThrow = (message) => {
console.log(message);
throw new Error(message);
}
const memoized = memoizeOne(willThrow);
let firstError;
let secondError;
try {
memoized('first message');
// console.log => 'first message'
} catch (e) {
firstError = e;
}
try {
memoized('first message');
// console.log => 'first message'
// even though the arguments are the same the result function was called again
} catch (e) {
secondError = e;
}
// result is regenerated and not cached
console.log(firstError === secondError);
// false
Thanks @ChristopherChudzicki for raising this issue and for the initial PR. Thanks to @scinos and @jamiebuilds for working this through with me.
Improvements
- Moving to
babel 7
#34 - Moving to
flow
0.79.1
#34 - Added example for custom equality function with multiple arguments to
README
#29. Thanks @andwilley!!
4.0.0
Changes
A bundle of joy 🎁
We are now publishing a number of bundle builds for your consumption needs!
dist/memoize-one.cjs.js
CommonJS bundledist/memoize-one.esm.js
ESM bundledist/memoize-one.min.js
UMD bundle (production build)dist/memoize-one.js
UMD bundle (development build)
This was listed as a breaking change 💥 - even though there are no api changes. The only changes are to the names and paths of the build files.
Bumping flow
We are now on the latest version of flow
: 0.75
.
3.1.1
Fixes
- We had an error in IE11 due to manually setting the
.length
property of our result function (added in3.1.0
). For now we have rolled back the feature and deprecated3.1.0
which added it. We could have wrapped the code in atry/catch
but we where not sure of the performance implications of going so. Thanks @eugene1g for finding this and @theKashey for helping work through it
3.1.0
This release has been deprecated on npm due to a critical bug in IE11. Please use
3.1.1
.
Features
- We now add the correct
.length
property to the result function. Thanks @theKashey for this one! - We now add a
.name
to the result function for improved debugging. Thanks @theKashey!
Other
- We now publish a esm module build! Thanks @Andarist!
- Upgraded to the latest
flowtype
- Moved from
mocha
tojest
- Upgrade all dependences to the latest versions
3.0.0
As with 2.0.0 this release has no javascript api changes. This version bump is the result of this pull request: #12
In this pull request the flow types for memoize-one where improved to be more correct. In doing so the flow type became a little tighter and more correct. There may be a situation where some code could potentially be relying on the less stringent type checking and in which case this change would break their code. As this is a change in public api that may possibility by some remote chance break a consumer - I thought it safest to do a major version bump.
2.0.0
I have created a github release for this major version bump because I thought it warranted an explanation.
This release has no javascript api changes so you can probably upgrade without any issues. The version bump is because of this pull request: #9.
This major version bump was the result of removing module
from package.json
:
- "module": "src/index.js",
module
is used to expose raw es6 sources for bundlers. It seems like the main use case for using module
is to allow removing duplicate imports via tree shaking. A few problems with module
in memoize-one
:
- The file itself was the raw source file. This meant that it would require the consumer to have the correct environment or babel setup for the file to be parsed correctly. This would mean that consumers would need and environment that supported: babel-preset-es2015, babel-plugin-transform-object-rest-spread and babel-plugin-transform-flow-strip-types.
- The file contained flow types. This is similar to the previous issue where it forced consumers to have the correct babel plugins set up. If you where not using the strip-flow-types babel plugin then your build would throw errors.
My thoughts on what would be the ideal module
:
compiled es5 source with es6 imports.
Given that memoize-one
has no dependencies there is no tree shaking advances in exposing it through module
.
Given that some people may have been explicitly relying on using the module
in memoize-one
previously I have made it a major version bump to remove it. While I expect that most module bundlers would have simply switched to main
with no issues - I wanted to be really safe and just do a major version bump. I think that module
is a public api and removing it therefore constitutes a break in api.