Skip to content

Releases: alexreardon/memoize-one

5.0.0

17 Dec 04:15
Compare
Choose a tag to compare

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

11 Dec 23:27
Compare
Choose a tag to compare

🛑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

07 Nov 02:15
Compare
Choose a tag to compare
  • Upgrading to flow 0.85
  • Upgrading dev deps

4.0.2

31 Aug 06:43
Compare
Choose a tag to compare

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

31 Aug 01:44
Compare
Choose a tag to compare

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

29 Jun 03:55
Compare
Choose a tag to compare

Changes

A bundle of joy 🎁

We are now publishing a number of bundle builds for your consumption needs!

  • dist/memoize-one.cjs.js CommonJS bundle
  • dist/memoize-one.esm.js ESM bundle
  • dist/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

22 Mar 08:16
Compare
Choose a tag to compare

Fixes

  • We had an error in IE11 due to manually setting the .length property of our result function (added in 3.1.0). For now we have rolled back the feature and deprecated 3.1.0 which added it. We could have wrapped the code in a try/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

22 Mar 00:08
Compare
Choose a tag to compare

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 to jest
  • Upgrade all dependences to the latest versions

3.0.0

15 May 07:16
Compare
Choose a tag to compare

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

05 May 12:32
Compare
Choose a tag to compare

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.