NGXS 3.0 marked a huge milestone for the project and today I’m excited to announce 3.1 which is packed with features, fixes and performance improvements. Its so big we should probably call it 4.0 but hey we are doing semver here. So what landed?

Selectors

3.1 is mainly focused around selectors. We’ve always had selectors but those selectors were bound to the state they were on.

We enhanced our core selectors by adding the ability to join multiple selectors together like:

@Selector([Zoo, Park.location]) static getAnimals(myState, zoo, locations) { ... }

In addition to selector joins, you can now pass arguments to a selector like:

@Selector() static getAnimals(state) {

return (animalType) => { ... };

}

We also introduce a new concept called meta selectors. This allows you to create selectors on any class so selectors no longer have to be tied to a specific class. And of course they are memoized for high performance!

Migration Strategies for Storage Plugin

When we design our state it often changes from version to version. If we are using local storage to back our state it can get out of sync. In 3.1, we introduced a way to migrate state from version to version.

Dev Mode

We introduced a feature called dev mode for the store. This allows plugin authors to take advantage of the flag to allow better error messages and runtime checking.

Freeze Store

When dev mode is enabled, the store will automatically freeze the state so you can’t mutate the state. When switched into production, this runtime check will go away for maximum performance. This is out of the box, all you have to do is flip on the dev mode flag!

Performance

Performance is critical for any applications, I would almost argue its one of the top features you can give your users. One of the biggest things in Angular that can kill performance is Zones. Zones capture events such as XHR/Websocket/DOM Events/etc and tell Angular to run change detection. This is part of what makes Angular magical but it can also be a burden if you are running a high volume of a operations within a short duration of each other. When we are using observables and the async pipe, Angular can subscribe to the observable know when to run change detection based on changes with the observables.

Given we mostly deal with observables in NGXS, we decided to run all our operations outside of zones. Your gonna see a noticeable performance difference because of this!

After doing this we realized there were also places where users wanted to subscribe to the result of a dispatch and just set a property. In previous versions, this would almost always result in you having to run a mark for check on the change detector. In 3.1, when you subscribe to a dispatch we return the user to a zone which syncs with the change detector and eliminates the need for that hack!

What else landed?

State Reset — When unit testing you often want to put your state in a specific state. This would require you to run your operations in a build up/build down scenario (which is good idea btw) but it can be burdensome so in 3.1 we added a reset method on the store that enables you to reset the entire state of the store with a new object.

Snapshot selects can use state classes for selectors.

6 bug fixes

Whats next?

We have much more planned for the future, some things on the horizon are schematics and maybe even our own devtools plugin! Stay tuned!