Version 2.0.0 with improved references. In addition to much more powerful references, there are also breaking changes with the passed event arguments and how you access the list of instances from a Immstruct instance.
Breaking Changes
-
Removes instances property from API. No longer a property
.instances
on the Immstruct instance which allow you to access the list of instances. It's now a methodinstance
which allow you to get either the complete list, if no arguments, or a specific instance given by key as first argument.var immstruct = require('immstruct'); immstruct('foo', {}); immstruct.instance(); // => { 'foo': Immutable.Map } immstruct.instance('foo'); // => Immutable.Map // Same for instances of Immstruct: var localImmstruct = new immstruct.Immstruct(); localImmstruct.get('foo', {}); localImmstruct.instance(); // => { 'foo': Immutable.Map } localImmstruct.instance('foo'); // => Immutable.Map
-
References should now much more powerful and will listen to changes down the tree or on objects that are created after a reference is initiated. See #60 for more information. You can now do things as:
var structure = immstruct({ someBox: { message: 'Hello World!' } }); var ref = structure.reference('someBox'); ref.observe(function () { // Called when data the path 'someBox' is changed. // Also called when the data at ['someBox', 'message'] is changed. }); // Update the data using the ref ref.cursor().update(function () { return 'updated'; }); // Update the data using the initial structure structure.cursor(['someBox', 'message']).update(function () { return 'updated again'; });
-
Changes order of arguments for all events. See #64. New order is documented as:
swap
: Emitted when any cursor is updated (new information is set).
Triggered in any change, both change, add and delete. One use case for
this is to re-render design components. Structures passed as arguments
are scoped to the path passed to the reference.
Callback is passed arguments:newStructure
,oldStructure
,keyPath
.next-animation-frame
: Same asswap
, but only emitted on animation frame. Could use with many render updates and better performance. Callback is passed arguments:newStructure
,oldStructure
,keyPath
.change
: Emitted when data/value is updated and it existed before. Emits values:newValue
,oldValue
andpath
.delete
: Emitted when data/value is removed. Emits value:removedValue
andpath
.add
: Emitted when new data/value is added. Emits value:newValue
andpath
.
-
Now, as on
swap
for normal immstruct events, the passed arguments for the event is the root, not guaranteed to be the actual changed value. The structure is how ever scoped to the path passed in to the reference.For instance:
var structure = immstruct({ 'foo': { 'bar': 'hello' } }); var ref = structure.reference('foo'); ref.observe(function (newData, oldData, keyPath) { keyPath.should.eql(['foo', 'bar']); newData.toJS().should.eql({ 'bar': 'updated' }); oldData.toJS().should.eql({ 'bar': 'hello' }); }); ref.cursor().update(['bar'], function () { return 'updated'; });
For type specific events, how ever, the actual changed value is passed, not the root data.
For instance:
var structure = immstruct({ 'foo': { 'bar': 'hello' } }); var ref = structure.reference('foo'); ref.observe('change', function (newValue, oldValue, keyPath) { keyPath.should.eql(['foo', 'bar']); newData.should.eql('updated'); oldData.should.eql('hello'); }); ref.cursor().update(['bar'], function () { return 'updated'; });
Additions
-
Adds ability to create references from cursors
var structure = immstruct({ foo: 'bar' }); var myCursor = structure.cursor('foo'); var refToMyCursor = structure.reference(myCursor);
-
Adds ability to create child cursors (see #74) based on keyPath.
var structure = immstruct({ foo: { bar: 'Hello' } }); var refToFoo = structure.reference('foo'); var refToBar = refToFoo.reference('bar');
-
Add ability to provide a limit to cap history
Implement the ability to have history capped to a certain number of operations which is good for long running systems or heavy data use.
By specifying the optional limit, the history mechanism will release old records once it hits the threshold.
Default if not passed is Infinity.
// optionalKey and/or optionalLimit can be omitted from the call var optLimit = 10; // only keep last 10 of history, default Infinity var structure = immstruct.withHistory('optKey', optLimit, { 'foo': 'bar' }); var structureNoKey = immstruct.withHistory(optLimit, { 'foo': 'bar' }); // Or with no limit var structureNoKeyUnlimited = immstruct.withHistory({ 'foo': 'bar' }); var structureKeyUnlimited = immstruct.withHistory('foo', { 'foo': 'bar' });
-
Added event type
any
. With the same semantics asadd
,change
ordelete
,any
is triggered for all types of changes. Differs from swap in the arguments that it is passed. Is passednewValue
(or undefined),oldValue
(or undefined) and fullkeyPath
. New and old value are the changed value, not relative/scoped to the reference path as withswap
. -
Adds support for react-native
Bugfixes
- Makes animation frame queue per instance. Fixes #49
- Fixes IE8 'Expected identifier' error as "super" is a reserved keyword in IE8. See #69
- Adds function names to change listeners decorators for easier debugging
- Adds support for falsy keyPaths. Fixes #50
- Optimizes the render loop / event handling. Vastly improves performance and number of operations per second. See more info at #56 and #60.