Mutate a frozen object with a change-set and you get a new frozen object that is a merge, or an overlay, of the change-set on top of the original object. Again, this is a deep-merge that also you to works with Arrays, Sets, Maps, and your own custom classes. For the brave: you can provide custom freeze and merge functions.
Using TypeScript you get all the goodies of generics, enforcing the validity of the change-set, Readonly returned types and interfaces for the custom functions.
Enough talking. Let’s dive in…