immutable 3.7.2 → 3.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -11
- package/contrib/cursor/__tests__/Cursor.ts +34 -0
- package/contrib/cursor/index.d.ts +3 -0
- package/contrib/cursor/index.js +34 -2
- package/dist/immutable.d.ts +592 -521
- package/dist/immutable.js +1965 -1892
- package/dist/immutable.min.js +28 -41
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ Just add a reference with a relative path to the type declarations at the top
|
|
|
86
86
|
of your file.
|
|
87
87
|
|
|
88
88
|
```javascript
|
|
89
|
-
///<reference path='./node_modules/immutable/dist/
|
|
89
|
+
///<reference path='./node_modules/immutable/dist/immutable.d.ts'/>
|
|
90
90
|
import Immutable = require('immutable');
|
|
91
91
|
var map1: Immutable.Map<string, number>;
|
|
92
92
|
map1 = Immutable.Map({a:1, b:2, c:3});
|
|
@@ -116,18 +116,31 @@ and especially well with an application designed using the ideas of [Flux][].
|
|
|
116
116
|
|
|
117
117
|
When data is passed from above rather than being subscribed to, and you're only
|
|
118
118
|
interested in doing work when something has changed, you can use equality.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
|
|
120
|
+
Immutable collections should be treated as *values* rather than *objects*. While
|
|
121
|
+
objects represents some thing which could change over time, a value represents
|
|
122
|
+
the state of that thing at a particular instance of time. This principle is most
|
|
123
|
+
important to understanding the appropriate use of immutable data. In order to
|
|
124
|
+
treat Immutable.js collections as values, it's important to use the
|
|
125
|
+
`Immutable.is()` function or `.equals()` method to determine value equality
|
|
126
|
+
instead of the `===` operator which determines object reference identity.
|
|
122
127
|
|
|
123
128
|
```javascript
|
|
124
129
|
var map1 = Immutable.Map({a:1, b:2, c:3});
|
|
125
130
|
var map2 = map1.set('b', 2);
|
|
126
|
-
assert(map1 ===
|
|
131
|
+
assert(map1.equals(map2) === true);
|
|
127
132
|
var map3 = map1.set('b', 50);
|
|
128
|
-
assert(map1
|
|
133
|
+
assert(map1.equals(map3) === false);
|
|
129
134
|
```
|
|
130
135
|
|
|
136
|
+
Note: As a performance optimization `Immutable` attempts to return the existing
|
|
137
|
+
collection when an operation would result in an identical collection, allowing
|
|
138
|
+
for using `===` reference equality to determine if something definitely has not
|
|
139
|
+
changed. This can be extremely useful when used within memoization function
|
|
140
|
+
which would prefer to re-run the function if a deeper equality check could
|
|
141
|
+
potentially be more costly. The `===` equality check is also used internally by
|
|
142
|
+
`Immutable.is` and `.equals()` as a performance optimization.
|
|
143
|
+
|
|
131
144
|
If an object is immutable, it can be "copied" simply by making another reference
|
|
132
145
|
to it instead of copying the entire object. Because a reference is much smaller
|
|
133
146
|
than the object itself, this results in memory savings and a potential boost in
|
|
@@ -209,6 +222,26 @@ Immutable.Seq(myObject).map(x => x * x).toObject();
|
|
|
209
222
|
// { a: 1, b: 4, c: 9 }
|
|
210
223
|
```
|
|
211
224
|
|
|
225
|
+
Keep in mind, when using JS objects to construct Immutable Maps, that
|
|
226
|
+
JavaScript Object properties are always strings, even if written in a quote-less
|
|
227
|
+
shorthand, while Immutable Maps accept keys of any type.
|
|
228
|
+
|
|
229
|
+
```js
|
|
230
|
+
var obj = { 1: "one" };
|
|
231
|
+
Object.keys(obj); // [ "1" ]
|
|
232
|
+
obj["1"]; // "one"
|
|
233
|
+
obj[1]; // "one"
|
|
234
|
+
|
|
235
|
+
var map = Immutable.fromJS(obj);
|
|
236
|
+
map.get("1"); // "one"
|
|
237
|
+
map.get(1); // undefined
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Property access for JavaScript Objects first converts the key to a string, but
|
|
241
|
+
since Immutable Map keys can be of any type the argument to `get()` is
|
|
242
|
+
not altered.
|
|
243
|
+
|
|
244
|
+
|
|
212
245
|
### Converts back to raw JavaScript objects.
|
|
213
246
|
|
|
214
247
|
All `immutable` Iterables can be converted to plain JavaScript Arrays and
|
|
@@ -337,8 +370,9 @@ data, performing a deep equality check if necessary.
|
|
|
337
370
|
```javascript
|
|
338
371
|
var map1 = Immutable.Map({a:1, b:1, c:1});
|
|
339
372
|
var map2 = Immutable.Map({a:1, b:1, c:1});
|
|
340
|
-
assert(map1 !== map2);
|
|
341
|
-
assert(Immutable.is(map1, map2)
|
|
373
|
+
assert(map1 !== map2); // two different instances
|
|
374
|
+
assert(Immutable.is(map1, map2)); // have equivalent values
|
|
375
|
+
assert(map1.equals(map2)); // alternatively use the equals method
|
|
342
376
|
```
|
|
343
377
|
|
|
344
378
|
`Immutable.is()` uses the same measure of equality as [Object.is][]
|
|
@@ -359,9 +393,9 @@ Batching Mutations
|
|
|
359
393
|
> — Rich Hickey, Clojure
|
|
360
394
|
|
|
361
395
|
Applying a mutation to create a new immutable object results in some overhead,
|
|
362
|
-
which can add up to a performance penalty. If you need to apply a series
|
|
363
|
-
mutations locally before returning, `Immutable` gives you the ability to
|
|
364
|
-
a temporary mutable (transient) copy of a collection and apply a batch of
|
|
396
|
+
which can add up to a minor performance penalty. If you need to apply a series
|
|
397
|
+
of mutations locally before returning, `Immutable` gives you the ability to
|
|
398
|
+
create a temporary mutable (transient) copy of a collection and apply a batch of
|
|
365
399
|
mutations in a performant manner by using `withMutations`. In fact, this is
|
|
366
400
|
exactly how `Immutable` applies complex mutations itself.
|
|
367
401
|
|
|
@@ -381,6 +415,12 @@ Note: `immutable` also provides `asMutable` and `asImmutable`, but only
|
|
|
381
415
|
encourages their use when `withMutations` will not suffice. Use caution to not
|
|
382
416
|
return a mutable copy, which could result in undesired behavior.
|
|
383
417
|
|
|
418
|
+
*Important!*: Only a select few methods can be used in `withMutations` including
|
|
419
|
+
`set`, `push` and `pop`. These methods can be applied directly against a
|
|
420
|
+
persistent data-structure where other methods like `map`, `filter`, `sort`,
|
|
421
|
+
and `splice` will always return new immutable data-structures and never mutate
|
|
422
|
+
a mutable collection.
|
|
423
|
+
|
|
384
424
|
|
|
385
425
|
Documentation
|
|
386
426
|
-------------
|
|
@@ -354,4 +354,38 @@ describe('Cursor', () => {
|
|
|
354
354
|
);
|
|
355
355
|
});
|
|
356
356
|
|
|
357
|
+
it('can get Record value as a property', () => {
|
|
358
|
+
var User = Immutable.Record({ name: 'John' });
|
|
359
|
+
var users = Immutable.List.of(new User());
|
|
360
|
+
var data = Immutable.Map({'users': users});
|
|
361
|
+
var cursor = Cursor.from(data, ['users']);
|
|
362
|
+
expect(cursor.first().name).toBe('John');
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it('can set value of a cursor directly', () => {
|
|
366
|
+
var onChange = jest.genMockFunction();
|
|
367
|
+
var data = Immutable.fromJS({a:1});
|
|
368
|
+
var c = Cursor.from(data, ['a'], onChange);
|
|
369
|
+
var c1 = c.set(2);
|
|
370
|
+
expect(c1.deref()).toBe(2);
|
|
371
|
+
expect(onChange).lastCalledWith(
|
|
372
|
+
Immutable.fromJS({a:2}),
|
|
373
|
+
data,
|
|
374
|
+
['a']
|
|
375
|
+
);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
it('can set value of a cursor to undefined directly', () => {
|
|
379
|
+
var onChange = jest.genMockFunction();
|
|
380
|
+
var data = Immutable.fromJS({a:1});
|
|
381
|
+
var c = Cursor.from(data, ['a'], onChange);
|
|
382
|
+
var c1 = c.set(undefined);
|
|
383
|
+
expect(c1.deref()).toBe(undefined);
|
|
384
|
+
expect(onChange).lastCalledWith(
|
|
385
|
+
Immutable.fromJS({a:undefined}),
|
|
386
|
+
data,
|
|
387
|
+
['a']
|
|
388
|
+
);
|
|
389
|
+
});
|
|
390
|
+
|
|
357
391
|
});
|
|
@@ -91,8 +91,11 @@ declare module 'immutable/contrib/cursor' {
|
|
|
91
91
|
/**
|
|
92
92
|
* Sets `value` at `key` in the cursor, returning a new cursor to the same
|
|
93
93
|
* point in the new data.
|
|
94
|
+
*
|
|
95
|
+
* If only one parameter is provided, it is set directly as the cursor's value.
|
|
94
96
|
*/
|
|
95
97
|
set(key: any, value: any): Cursor;
|
|
98
|
+
set(value: any): Cursor;
|
|
96
99
|
|
|
97
100
|
/**
|
|
98
101
|
* Deletes `key` from the cursor, returning a new cursor to the same
|
package/contrib/cursor/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var Iterable = Immutable.Iterable;
|
|
|
20
20
|
var Iterator = Iterable.Iterator;
|
|
21
21
|
var Seq = Immutable.Seq;
|
|
22
22
|
var Map = Immutable.Map;
|
|
23
|
+
var Record = Immutable.Record;
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
function cursorFrom(rootData, keyPath, onChange) {
|
|
@@ -85,7 +86,11 @@ IndexedCursorPrototype.getIn = function(keyPath, notSetValue) {
|
|
|
85
86
|
|
|
86
87
|
IndexedCursorPrototype.set =
|
|
87
88
|
KeyedCursorPrototype.set = function(key, value) {
|
|
88
|
-
|
|
89
|
+
if(arguments.length === 1) {
|
|
90
|
+
return updateCursor(this, function() { return key; }, []);
|
|
91
|
+
} else {
|
|
92
|
+
return updateCursor(this, function (m) { return m.set(key, value); }, [key]);
|
|
93
|
+
}
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
IndexedCursorPrototype.push = function(/* values */) {
|
|
@@ -251,7 +256,34 @@ function makeCursor(rootData, keyPath, onChange, value) {
|
|
|
251
256
|
}
|
|
252
257
|
var size = value && value.size;
|
|
253
258
|
var CursorClass = Iterable.isIndexed(value) ? IndexedCursor : KeyedCursor;
|
|
254
|
-
|
|
259
|
+
var cursor = new CursorClass(rootData, keyPath, onChange, size);
|
|
260
|
+
|
|
261
|
+
if (value instanceof Record) {
|
|
262
|
+
defineRecordProperties(cursor, value);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return cursor;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function defineRecordProperties(cursor, value) {
|
|
269
|
+
try {
|
|
270
|
+
value._keys.forEach(setProp.bind(undefined, cursor));
|
|
271
|
+
} catch (error) {
|
|
272
|
+
// Object.defineProperty failed. Probably IE8.
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function setProp(prototype, name) {
|
|
277
|
+
Object.defineProperty(prototype, name, {
|
|
278
|
+
get: function() {
|
|
279
|
+
return this.get(name);
|
|
280
|
+
},
|
|
281
|
+
set: function(value) {
|
|
282
|
+
if (!this.__ownerID) {
|
|
283
|
+
throw new Error('Cannot set on an immutable record.');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
});
|
|
255
287
|
}
|
|
256
288
|
|
|
257
289
|
function wrappedValue(cursor, keyPath, value) {
|