immutable 4.0.0-rc.10 → 4.0.0-rc.15
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/LICENSE +1 -1
- package/README.md +174 -100
- package/dist/immutable.d.ts +824 -528
- package/dist/immutable.es.js +626 -509
- package/dist/immutable.js +657 -531
- package/dist/immutable.js.flow +937 -264
- package/dist/immutable.min.js +53 -36
- package/package.json +7 -11
- package/contrib/cursor/README.md +0 -43
- package/contrib/cursor/__tests__/Cursor.ts.skip +0 -395
- package/contrib/cursor/index.d.ts +0 -287
- package/contrib/cursor/index.js +0 -360
- package/dist/immutable-nonambient.d.ts +0 -5333
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2014-present,
|
|
3
|
+
Copyright (c) 2014-present, Lee Byron and other contributors.
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
|
-
Immutable collections for JavaScript
|
|
2
|
-
====================================
|
|
1
|
+
# Immutable collections for JavaScript
|
|
3
2
|
|
|
4
|
-
[](https://github.com/immutable-js/immutable-js/actions/workflows/ci.yml?query=branch%3Amain) [Chat on slack](https://immutable-js.slack.com)
|
|
4
|
+
|
|
5
|
+
[Read the docs](https://immutable-js.com) and eat your vegetables.
|
|
6
|
+
|
|
7
|
+
Docs are automatically generated from [README.md][] and [immutable.d.ts][].
|
|
8
|
+
Please contribute! Also, don't miss the [wiki][] which contains articles on
|
|
9
|
+
additional specific topics. Can't find something? Open an [issue][].
|
|
10
|
+
|
|
11
|
+
**Table of contents:**
|
|
12
|
+
|
|
13
|
+
- [Introduction](#introduction)
|
|
14
|
+
- [Getting started](#getting-started)
|
|
15
|
+
- [The case for Immutability](#the-case-for-immutability)
|
|
16
|
+
- [JavaScript-first API](#javaScript-first-api)
|
|
17
|
+
- [Nested Structures](#nested-structures)
|
|
18
|
+
- [Equality treats Collections as Values](#equality-treats-collections-as-values)
|
|
19
|
+
- [Batching Mutations](#batching-mutations)
|
|
20
|
+
- [Lazy Seq](#lazy-seq)
|
|
21
|
+
- [Additional Tools and Resources](#additional-tools-and-resources)
|
|
22
|
+
- [Contributing](#contributing)
|
|
23
|
+
|
|
24
|
+
## Introduction
|
|
5
25
|
|
|
6
26
|
[Immutable][] data cannot be changed once created, leading to much simpler
|
|
7
27
|
application development, no defensive copying, and enabling advanced memoization
|
|
@@ -22,16 +42,18 @@ intermediate representations. Create some `Seq` with `Range` and `Repeat`.
|
|
|
22
42
|
|
|
23
43
|
Want to hear more? Watch the presentation about Immutable.js:
|
|
24
44
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
[Persistent]: http://en.wikipedia.org/wiki/Persistent_data_structure
|
|
28
|
-
[Immutable]: http://en.wikipedia.org/wiki/Immutable_object
|
|
29
|
-
[hash maps tries]: http://en.wikipedia.org/wiki/Hash_array_mapped_trie
|
|
30
|
-
[vector tries]: http://hypirion.com/musings/understanding-persistent-vector-pt-1
|
|
45
|
+
[](https://youtu.be/I7IdS-PbEgI)
|
|
31
46
|
|
|
47
|
+
[README.md]: https://github.com/immutable-js/immutable-js/blob/main/README.md
|
|
48
|
+
[immutable.d.ts]: https://github.com/immutable-js/immutable-js/blob/main/type-definitions/immutable.d.ts
|
|
49
|
+
[wiki]: https://github.com/immutable-js/immutable-js/wiki
|
|
50
|
+
[issue]: https://github.com/immutable-js/immutable-js/issues
|
|
51
|
+
[Persistent]: https://en.wikipedia.org/wiki/Persistent_data_structure
|
|
52
|
+
[Immutable]: https://en.wikipedia.org/wiki/Immutable_object
|
|
53
|
+
[hash maps tries]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie
|
|
54
|
+
[vector tries]: https://hypirion.com/musings/understanding-persistent-vector-pt-1
|
|
32
55
|
|
|
33
|
-
Getting started
|
|
34
|
-
---------------
|
|
56
|
+
## Getting started
|
|
35
57
|
|
|
36
58
|
Install `immutable` using npm.
|
|
37
59
|
|
|
@@ -39,14 +61,21 @@ Install `immutable` using npm.
|
|
|
39
61
|
npm install immutable
|
|
40
62
|
```
|
|
41
63
|
|
|
64
|
+
Or install using yarn.
|
|
65
|
+
|
|
66
|
+
```shell
|
|
67
|
+
yarn add immutable
|
|
68
|
+
```
|
|
69
|
+
|
|
42
70
|
Then require it into any module.
|
|
43
71
|
|
|
44
72
|
<!-- runkit:activate -->
|
|
73
|
+
|
|
45
74
|
```js
|
|
46
75
|
const { Map } = require('immutable');
|
|
47
76
|
const map1 = Map({ a: 1, b: 2, c: 3 });
|
|
48
77
|
const map2 = map1.set('b', 50);
|
|
49
|
-
map1.get('b') +
|
|
78
|
+
map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50
|
|
50
79
|
```
|
|
51
80
|
|
|
52
81
|
### Browser
|
|
@@ -55,7 +84,7 @@ Immutable.js has no dependencies, which makes it predictable to include in a Bro
|
|
|
55
84
|
|
|
56
85
|
It's highly recommended to use a module bundler like [webpack](https://webpack.github.io/),
|
|
57
86
|
[rollup](https://rollupjs.org/), or
|
|
58
|
-
[browserify](
|
|
87
|
+
[browserify](https://browserify.org/). The `immutable` npm module works
|
|
59
88
|
without any additional consideration. All examples throughout the documentation
|
|
60
89
|
will assume use of this kind of tool.
|
|
61
90
|
|
|
@@ -75,7 +104,7 @@ Use a script tag to directly add `Immutable` to the global scope:
|
|
|
75
104
|
</script>
|
|
76
105
|
```
|
|
77
106
|
|
|
78
|
-
Or use an AMD-style loader (such as [RequireJS](
|
|
107
|
+
Or use an AMD-style loader (such as [RequireJS](https://requirejs.org/)):
|
|
79
108
|
|
|
80
109
|
```js
|
|
81
110
|
require(['./immutable.min.js'], function (Immutable) {
|
|
@@ -89,7 +118,7 @@ require(['./immutable.min.js'], function (Immutable) {
|
|
|
89
118
|
### Flow & TypeScript
|
|
90
119
|
|
|
91
120
|
Use these Immutable collections and sequences as you would use native
|
|
92
|
-
collections in your [Flowtype](https://flowtype.org/) or [TypeScript](
|
|
121
|
+
collections in your [Flowtype](https://flowtype.org/) or [TypeScript](https://typescriptlang.org) programs while still taking
|
|
93
122
|
advantage of type generics, error detection, and auto-complete in your IDE.
|
|
94
123
|
|
|
95
124
|
Installing `immutable` via npm brings with it type definitions for Flow (v0.55.0 or higher)
|
|
@@ -104,11 +133,12 @@ lib. Include either `"target": "es2015"` or `"lib": "es2015"` in your
|
|
|
104
133
|
`tsc` command.
|
|
105
134
|
|
|
106
135
|
<!-- runkit:activate -->
|
|
136
|
+
|
|
107
137
|
```js
|
|
108
|
-
const { Map } = require(
|
|
138
|
+
const { Map } = require('immutable');
|
|
109
139
|
const map1 = Map({ a: 1, b: 2, c: 3 });
|
|
110
140
|
const map2 = map1.set('b', 50);
|
|
111
|
-
map1.get('b') +
|
|
141
|
+
map1.get('b') + ' vs. ' + map2.get('b'); // 2 vs. 50
|
|
112
142
|
```
|
|
113
143
|
|
|
114
144
|
#### Using TypeScript with Immutable.js v3 and earlier:
|
|
@@ -118,7 +148,7 @@ via relative path to the type definitions at the top of your file.
|
|
|
118
148
|
|
|
119
149
|
```js
|
|
120
150
|
///<reference path='./node_modules/immutable/dist/immutable.d.ts'/>
|
|
121
|
-
import Immutable from
|
|
151
|
+
import Immutable from 'immutable';
|
|
122
152
|
var map1: Immutable.Map<string, number>;
|
|
123
153
|
map1 = Immutable.Map({ a: 1, b: 2, c: 3 });
|
|
124
154
|
var map2 = map1.set('b', 50);
|
|
@@ -126,9 +156,7 @@ map1.get('b'); // 2
|
|
|
126
156
|
map2.get('b'); // 50
|
|
127
157
|
```
|
|
128
158
|
|
|
129
|
-
|
|
130
|
-
The case for Immutability
|
|
131
|
-
-------------------------
|
|
159
|
+
## The case for Immutability
|
|
132
160
|
|
|
133
161
|
Much of what makes application development difficult is tracking mutation and
|
|
134
162
|
maintaining state. Developing with immutable data encourages you to think
|
|
@@ -147,15 +175,16 @@ and especially well with an application designed using the ideas of [Flux][].
|
|
|
147
175
|
When data is passed from above rather than being subscribed to, and you're only
|
|
148
176
|
interested in doing work when something has changed, you can use equality.
|
|
149
177
|
|
|
150
|
-
Immutable collections should be treated as
|
|
178
|
+
Immutable collections should be treated as _values_ rather than _objects_. While
|
|
151
179
|
objects represent some thing which could change over time, a value represents
|
|
152
180
|
the state of that thing at a particular instance of time. This principle is most
|
|
153
181
|
important to understanding the appropriate use of immutable data. In order to
|
|
154
182
|
treat Immutable.js collections as values, it's important to use the
|
|
155
|
-
`Immutable.is()` function or `.equals()` method to determine
|
|
156
|
-
instead of the `===` operator which determines object
|
|
183
|
+
`Immutable.is()` function or `.equals()` method to determine _value equality_
|
|
184
|
+
instead of the `===` operator which determines object _reference identity_.
|
|
157
185
|
|
|
158
186
|
<!-- runkit:activate -->
|
|
187
|
+
|
|
159
188
|
```js
|
|
160
189
|
const { Map } = require('immutable');
|
|
161
190
|
const map1 = Map({ a: 1, b: 2, c: 3 });
|
|
@@ -173,6 +202,7 @@ potentially be more costly. The `===` equality check is also used internally by
|
|
|
173
202
|
`Immutable.is` and `.equals()` as a performance optimization.
|
|
174
203
|
|
|
175
204
|
<!-- runkit:activate -->
|
|
205
|
+
|
|
176
206
|
```js
|
|
177
207
|
const { Map } = require('immutable');
|
|
178
208
|
const map1 = Map({ a: 1, b: 2, c: 3 });
|
|
@@ -186,28 +216,28 @@ than the object itself, this results in memory savings and a potential boost in
|
|
|
186
216
|
execution speed for programs which rely on copies (such as an undo-stack).
|
|
187
217
|
|
|
188
218
|
<!-- runkit:activate -->
|
|
219
|
+
|
|
189
220
|
```js
|
|
190
221
|
const { Map } = require('immutable');
|
|
191
222
|
const map = Map({ a: 1, b: 2, c: 3 });
|
|
192
223
|
const mapCopy = map; // Look, "copies" are free!
|
|
193
224
|
```
|
|
194
225
|
|
|
195
|
-
[React]:
|
|
196
|
-
[Flux]:
|
|
226
|
+
[React]: https://reactjs.org/
|
|
227
|
+
[Flux]: https://facebook.github.io/flux/docs/in-depth-overview/
|
|
197
228
|
|
|
198
229
|
|
|
199
|
-
JavaScript-first API
|
|
200
|
-
--------------------
|
|
230
|
+
## JavaScript-first API
|
|
201
231
|
|
|
202
232
|
While Immutable.js is inspired by Clojure, Scala, Haskell and other functional
|
|
203
233
|
programming environments, it's designed to bring these powerful concepts to
|
|
204
234
|
JavaScript, and therefore has an Object-Oriented API that closely mirrors that
|
|
205
235
|
of [ES2015][] [Array][], [Map][], and [Set][].
|
|
206
236
|
|
|
207
|
-
[
|
|
208
|
-
[
|
|
209
|
-
[
|
|
210
|
-
[
|
|
237
|
+
[es2015]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla
|
|
238
|
+
[array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
|
|
239
|
+
[map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
|
|
240
|
+
[set]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
|
|
211
241
|
|
|
212
242
|
The difference for the immutable collections is that methods which would mutate
|
|
213
243
|
the collection, like `push`, `set`, `unshift` or `splice`, instead return a new
|
|
@@ -215,9 +245,10 @@ immutable collection. Methods which return new arrays, like `slice` or `concat`,
|
|
|
215
245
|
instead return new immutable collections.
|
|
216
246
|
|
|
217
247
|
<!-- runkit:activate -->
|
|
248
|
+
|
|
218
249
|
```js
|
|
219
250
|
const { List } = require('immutable');
|
|
220
|
-
const list1 = List([
|
|
251
|
+
const list1 = List([1, 2]);
|
|
221
252
|
const list2 = list1.push(3, 4, 5);
|
|
222
253
|
const list3 = list2.unshift(0);
|
|
223
254
|
const list4 = list1.concat(list2, list3);
|
|
@@ -234,6 +265,7 @@ found on `Immutable.Set`, including collection operations like `forEach()`
|
|
|
234
265
|
and `map()`.
|
|
235
266
|
|
|
236
267
|
<!-- runkit:activate -->
|
|
268
|
+
|
|
237
269
|
```js
|
|
238
270
|
const { Map } = require('immutable');
|
|
239
271
|
const alpha = Map({ a: 1, b: 2, c: 3, d: 4 });
|
|
@@ -248,6 +280,7 @@ accepts plain JavaScript Arrays and Objects anywhere a method expects a
|
|
|
248
280
|
`Collection`.
|
|
249
281
|
|
|
250
282
|
<!-- runkit:activate -->
|
|
283
|
+
|
|
251
284
|
```js
|
|
252
285
|
const { Map, List } = require('immutable');
|
|
253
286
|
const map1 = Map({ a: 1, b: 2, c: 3, d: 4 });
|
|
@@ -255,9 +288,9 @@ const map2 = Map({ c: 10, a: 20, t: 30 });
|
|
|
255
288
|
const obj = { d: 100, o: 200, g: 300 };
|
|
256
289
|
const map3 = map1.merge(map2, obj);
|
|
257
290
|
// Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 }
|
|
258
|
-
const list1 = List([
|
|
259
|
-
const list2 = List([
|
|
260
|
-
const array = [
|
|
291
|
+
const list1 = List([1, 2, 3]);
|
|
292
|
+
const list2 = List([4, 5, 6]);
|
|
293
|
+
const array = [7, 8, 9];
|
|
261
294
|
const list3 = list1.concat(list2, array);
|
|
262
295
|
// List [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
|
263
296
|
```
|
|
@@ -269,10 +302,13 @@ native API. Because Seq evaluates lazily and does not cache intermediate
|
|
|
269
302
|
results, these operations can be extremely efficient.
|
|
270
303
|
|
|
271
304
|
<!-- runkit:activate -->
|
|
305
|
+
|
|
272
306
|
```js
|
|
273
307
|
const { Seq } = require('immutable');
|
|
274
308
|
const myObject = { a: 1, b: 2, c: 3 };
|
|
275
|
-
Seq(myObject)
|
|
309
|
+
Seq(myObject)
|
|
310
|
+
.map(x => x * x)
|
|
311
|
+
.toObject();
|
|
276
312
|
// { a: 1, b: 4, c: 9 }
|
|
277
313
|
```
|
|
278
314
|
|
|
@@ -281,22 +317,22 @@ JavaScript Object properties are always strings, even if written in a quote-less
|
|
|
281
317
|
shorthand, while Immutable Maps accept keys of any type.
|
|
282
318
|
|
|
283
319
|
<!-- runkit:activate -->
|
|
320
|
+
|
|
284
321
|
```js
|
|
285
322
|
const { fromJS } = require('immutable');
|
|
286
323
|
|
|
287
|
-
const obj = { 1:
|
|
324
|
+
const obj = { 1: 'one' };
|
|
288
325
|
console.log(Object.keys(obj)); // [ "1" ]
|
|
289
|
-
console.log(obj[
|
|
326
|
+
console.log(obj['1'], obj[1]); // "one", "one"
|
|
290
327
|
|
|
291
328
|
const map = fromJS(obj);
|
|
292
|
-
console.log(map.get(
|
|
329
|
+
console.log(map.get('1'), map.get(1)); // "one", undefined
|
|
293
330
|
```
|
|
294
331
|
|
|
295
332
|
Property access for JavaScript Objects first converts the key to a string, but
|
|
296
333
|
since Immutable Map keys can be of any type the argument to `get()` is
|
|
297
334
|
not altered.
|
|
298
335
|
|
|
299
|
-
|
|
300
336
|
### Converts back to raw JavaScript objects.
|
|
301
337
|
|
|
302
338
|
All Immutable.js Collections can be converted to plain JavaScript Arrays and
|
|
@@ -306,9 +342,10 @@ to `JSON.stringify` directly. They also respect the custom `toJSON()` methods of
|
|
|
306
342
|
nested objects.
|
|
307
343
|
|
|
308
344
|
<!-- runkit:activate -->
|
|
345
|
+
|
|
309
346
|
```js
|
|
310
347
|
const { Map, List } = require('immutable');
|
|
311
|
-
const deep = Map({ a: 1, b: 2, c: List([
|
|
348
|
+
const deep = Map({ a: 1, b: 2, c: List([3, 4, 5]) });
|
|
312
349
|
console.log(deep.toObject()); // { a: 1, b: 2, c: List [ 3, 4, 5 ] }
|
|
313
350
|
console.log(deep.toArray()); // [ 1, 2, List [ 3, 4, 5 ] ]
|
|
314
351
|
console.log(deep.toJS()); // { a: 1, b: 2, c: [ 3, 4, 5 ] }
|
|
@@ -318,7 +355,7 @@ JSON.stringify(deep); // '{"a":1,"b":2,"c":[3,4,5]}'
|
|
|
318
355
|
### Embraces ES2015
|
|
319
356
|
|
|
320
357
|
Immutable.js supports all JavaScript environments, including legacy
|
|
321
|
-
browsers (even
|
|
358
|
+
browsers (even IE11). However it also takes advantage of features added to
|
|
322
359
|
JavaScript in [ES2015][], the latest standard version of JavaScript, including
|
|
323
360
|
[Iterators][], [Arrow Functions][], [Classes][], and [Modules][]. It's inspired
|
|
324
361
|
by the native [Map][] and [Set][] collections added to ES2015.
|
|
@@ -330,17 +367,20 @@ browsers, they need to be translated to ES5.
|
|
|
330
367
|
// ES2015
|
|
331
368
|
const mapped = foo.map(x => x * x);
|
|
332
369
|
// ES5
|
|
333
|
-
var mapped = foo.map(function (x) {
|
|
370
|
+
var mapped = foo.map(function (x) {
|
|
371
|
+
return x * x;
|
|
372
|
+
});
|
|
334
373
|
```
|
|
335
374
|
|
|
336
|
-
All Immutable.js collections are [Iterable][
|
|
375
|
+
All Immutable.js collections are [Iterable][iterators], which allows them to be
|
|
337
376
|
used anywhere an Iterable is expected, such as when spreading into an Array.
|
|
338
377
|
|
|
339
378
|
<!-- runkit:activate -->
|
|
379
|
+
|
|
340
380
|
```js
|
|
341
381
|
const { List } = require('immutable');
|
|
342
|
-
const aList = List([
|
|
343
|
-
const anArray = [
|
|
382
|
+
const aList = List([1, 2, 3]);
|
|
383
|
+
const anArray = [0, ...aList, 4, 5]; // [ 0, 1, 2, 3, 4, 5 ]
|
|
344
384
|
```
|
|
345
385
|
|
|
346
386
|
Note: A Collection is always iterated in the same order, however that order may
|
|
@@ -348,20 +388,20 @@ not always be well defined, as is the case for the `Map` and `Set`.
|
|
|
348
388
|
|
|
349
389
|
[Iterators]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol
|
|
350
390
|
[Arrow Functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
|
|
351
|
-
[Classes]:
|
|
352
|
-
[Modules]:
|
|
391
|
+
[Classes]: https://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes
|
|
392
|
+
[Modules]: https://www.2ality.com/2014/09/es6-modules-final.html
|
|
353
393
|
|
|
354
394
|
|
|
355
|
-
Nested Structures
|
|
356
|
-
-----------------
|
|
395
|
+
## Nested Structures
|
|
357
396
|
|
|
358
397
|
The collections in Immutable.js are intended to be nested, allowing for deep
|
|
359
398
|
trees of data, similar to JSON.
|
|
360
399
|
|
|
361
400
|
<!-- runkit:activate -->
|
|
401
|
+
|
|
362
402
|
```js
|
|
363
403
|
const { fromJS } = require('immutable');
|
|
364
|
-
const nested = fromJS({ a: { b: { c: [
|
|
404
|
+
const nested = fromJS({ a: { b: { c: [3, 4, 5] } } });
|
|
365
405
|
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } }
|
|
366
406
|
```
|
|
367
407
|
|
|
@@ -370,37 +410,37 @@ most useful are `mergeDeep`, `getIn`, `setIn`, and `updateIn`, found on `List`,
|
|
|
370
410
|
`Map` and `OrderedMap`.
|
|
371
411
|
|
|
372
412
|
<!-- runkit:activate -->
|
|
413
|
+
|
|
373
414
|
```js
|
|
374
415
|
const { fromJS } = require('immutable');
|
|
375
|
-
const nested = fromJS({ a: { b: { c: [
|
|
416
|
+
const nested = fromJS({ a: { b: { c: [3, 4, 5] } } });
|
|
376
417
|
|
|
377
418
|
const nested2 = nested.mergeDeep({ a: { b: { d: 6 } } });
|
|
378
419
|
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } }
|
|
379
420
|
|
|
380
|
-
console.log(nested2.getIn([
|
|
421
|
+
console.log(nested2.getIn(['a', 'b', 'd'])); // 6
|
|
381
422
|
|
|
382
|
-
const nested3 = nested2.updateIn([
|
|
423
|
+
const nested3 = nested2.updateIn(['a', 'b', 'd'], value => value + 1);
|
|
383
424
|
console.log(nested3);
|
|
384
425
|
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }
|
|
385
426
|
|
|
386
|
-
const nested4 = nested3.updateIn([
|
|
427
|
+
const nested4 = nested3.updateIn(['a', 'b', 'c'], list => list.push(6));
|
|
387
428
|
// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }
|
|
388
429
|
```
|
|
389
430
|
|
|
431
|
+
## Equality treats Collections as Values
|
|
390
432
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
Immutable.js collections are treated as pure data *values*. Two immutable
|
|
395
|
-
collections are considered *value equal* (via `.equals()` or `is()`) if they
|
|
433
|
+
Immutable.js collections are treated as pure data _values_. Two immutable
|
|
434
|
+
collections are considered _value equal_ (via `.equals()` or `is()`) if they
|
|
396
435
|
represent the same collection of values. This differs from JavaScript's typical
|
|
397
|
-
|
|
436
|
+
_reference equal_ (via `===` or `==`) for Objects and Arrays which only
|
|
398
437
|
determines if two variables represent references to the same object instance.
|
|
399
438
|
|
|
400
439
|
Consider the example below where two identical `Map` instances are not
|
|
401
|
-
|
|
440
|
+
_reference equal_ but are _value equal_.
|
|
402
441
|
|
|
403
442
|
<!-- runkit:activate -->
|
|
443
|
+
|
|
404
444
|
```js
|
|
405
445
|
// First consider:
|
|
406
446
|
const obj1 = { a: 1, b: 2, c: 3 };
|
|
@@ -419,6 +459,7 @@ Value equality allows Immutable.js collections to be used as keys in Maps or
|
|
|
419
459
|
values in Sets, and retrieved with different but equivalent collections:
|
|
420
460
|
|
|
421
461
|
<!-- runkit:activate -->
|
|
462
|
+
|
|
422
463
|
```js
|
|
423
464
|
const { Map, Set } = require('immutable');
|
|
424
465
|
const map1 = Map({ a: 1, b: 2, c: 3 });
|
|
@@ -432,7 +473,7 @@ strings and numbers, but uses value equality for Immutable collections,
|
|
|
432
473
|
determining if both are immutable and all keys and values are equal
|
|
433
474
|
using the same measure of equality.
|
|
434
475
|
|
|
435
|
-
[
|
|
476
|
+
[object.is]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
|
436
477
|
|
|
437
478
|
#### Performance tradeoffs
|
|
438
479
|
|
|
@@ -454,10 +495,11 @@ out the possibility that they may be value-equal.
|
|
|
454
495
|
#### Return self on no-op optimization
|
|
455
496
|
|
|
456
497
|
When possible, Immutable.js avoids creating new objects for updates where no
|
|
457
|
-
change in
|
|
498
|
+
change in _value_ occurred, to allow for efficient _reference equality_ checking
|
|
458
499
|
to quickly determine if no change occurred.
|
|
459
500
|
|
|
460
501
|
<!-- runkit:activate -->
|
|
502
|
+
|
|
461
503
|
```js
|
|
462
504
|
const { Map } = require('immutable');
|
|
463
505
|
const originalMap = Map({ a: 1, b: 2, c: 3 });
|
|
@@ -470,6 +512,7 @@ of these operations occur independently, so two similar updates will not return
|
|
|
470
512
|
the same reference:
|
|
471
513
|
|
|
472
514
|
<!-- runkit:activate -->
|
|
515
|
+
|
|
473
516
|
```js
|
|
474
517
|
const { Map } = require('immutable');
|
|
475
518
|
const originalMap = Map({ a: 1, b: 2, c: 3 });
|
|
@@ -483,8 +526,7 @@ anotherUpdatedMap !== updatedMap;
|
|
|
483
526
|
anotherUpdatedMap.equals(updatedMap);
|
|
484
527
|
```
|
|
485
528
|
|
|
486
|
-
Batching Mutations
|
|
487
|
-
------------------
|
|
529
|
+
## Batching Mutations
|
|
488
530
|
|
|
489
531
|
> If a tree falls in the woods, does it make a sound?
|
|
490
532
|
>
|
|
@@ -498,15 +540,16 @@ which can add up to a minor performance penalty. If you need to apply a series
|
|
|
498
540
|
of mutations locally before returning, Immutable.js gives you the ability to
|
|
499
541
|
create a temporary mutable (transient) copy of a collection and apply a batch of
|
|
500
542
|
mutations in a performant manner by using `withMutations`. In fact, this is
|
|
501
|
-
exactly how
|
|
543
|
+
exactly how Immutable.js applies complex mutations itself.
|
|
502
544
|
|
|
503
545
|
As an example, building `list2` results in the creation of 1, not 3, new
|
|
504
546
|
immutable Lists.
|
|
505
547
|
|
|
506
548
|
<!-- runkit:activate -->
|
|
549
|
+
|
|
507
550
|
```js
|
|
508
551
|
const { List } = require('immutable');
|
|
509
|
-
const list1 = List([
|
|
552
|
+
const list1 = List([1, 2, 3]);
|
|
510
553
|
const list2 = list1.withMutations(function (list) {
|
|
511
554
|
list.push(4).push(5).push(6);
|
|
512
555
|
});
|
|
@@ -518,15 +561,13 @@ Note: Immutable.js also provides `asMutable` and `asImmutable`, but only
|
|
|
518
561
|
encourages their use when `withMutations` will not suffice. Use caution to not
|
|
519
562
|
return a mutable copy, which could result in undesired behavior.
|
|
520
563
|
|
|
521
|
-
|
|
564
|
+
_Important!_: Only a select few methods can be used in `withMutations` including
|
|
522
565
|
`set`, `push` and `pop`. These methods can be applied directly against a
|
|
523
566
|
persistent data-structure where other methods like `map`, `filter`, `sort`,
|
|
524
567
|
and `splice` will always return new immutable data-structures and never mutate
|
|
525
568
|
a mutable collection.
|
|
526
569
|
|
|
527
|
-
|
|
528
|
-
Lazy Seq
|
|
529
|
-
--------
|
|
570
|
+
## Lazy Seq
|
|
530
571
|
|
|
531
572
|
`Seq` describes a lazy operation, allowing them to efficiently chain
|
|
532
573
|
use of all the higher-order collection methods (such as `map` and `filter`)
|
|
@@ -546,7 +587,7 @@ For example, the following performs no work, because the resulting
|
|
|
546
587
|
|
|
547
588
|
```js
|
|
548
589
|
const { Seq } = require('immutable');
|
|
549
|
-
const oddSquares = Seq([
|
|
590
|
+
const oddSquares = Seq([1, 2, 3, 4, 5, 6, 7, 8])
|
|
550
591
|
.filter(x => x % 2 !== 0)
|
|
551
592
|
.map(x => x * x);
|
|
552
593
|
```
|
|
@@ -562,6 +603,7 @@ oddSquares.get(1); // 9
|
|
|
562
603
|
Any collection can be converted to a lazy Seq with `Seq()`.
|
|
563
604
|
|
|
564
605
|
<!-- runkit:activate -->
|
|
606
|
+
|
|
565
607
|
```js
|
|
566
608
|
const { Map, Seq } = require('immutable');
|
|
567
609
|
const map = Map({ a: 1, b: 2, c: 3 });
|
|
@@ -576,13 +618,14 @@ lazySeq
|
|
|
576
618
|
.flip()
|
|
577
619
|
.map(key => key.toUpperCase())
|
|
578
620
|
.flip();
|
|
579
|
-
// Seq { A: 1, B:
|
|
621
|
+
// Seq { A: 1, B: 2, C: 3 }
|
|
580
622
|
```
|
|
581
623
|
|
|
582
624
|
As well as expressing logic that would otherwise seem memory or time
|
|
583
625
|
limited, for example `Range` is a special kind of Lazy sequence.
|
|
584
626
|
|
|
585
627
|
<!-- runkit:activate -->
|
|
628
|
+
|
|
586
629
|
```js
|
|
587
630
|
const { Range } = require('immutable');
|
|
588
631
|
Range(1, Infinity)
|
|
@@ -594,50 +637,81 @@ Range(1, Infinity)
|
|
|
594
637
|
// 1006008
|
|
595
638
|
```
|
|
596
639
|
|
|
640
|
+
## Additional Tools and Resources
|
|
597
641
|
|
|
598
|
-
|
|
599
|
-
|
|
642
|
+
- [Atom-store](https://github.com/jameshopkins/atom-store/)
|
|
643
|
+
- A Clojure-inspired atom implementation in Javascript with configurability
|
|
644
|
+
for external persistance.
|
|
600
645
|
|
|
601
|
-
[
|
|
646
|
+
- [Chai Immutable](https://github.com/astorije/chai-immutable)
|
|
647
|
+
- If you are using the [Chai Assertion Library](https://chaijs.com/), this
|
|
648
|
+
provides a set of assertions to use against Immutable.js collections.
|
|
602
649
|
|
|
603
|
-
|
|
604
|
-
|
|
650
|
+
- [Fantasy-land](https://github.com/fantasyland/fantasy-land)
|
|
651
|
+
- Specification for interoperability of common algebraic structures in JavaScript.
|
|
605
652
|
|
|
606
|
-
|
|
607
|
-
|
|
653
|
+
- [Immutagen](https://github.com/pelotom/immutagen)
|
|
654
|
+
- A library for simulating immutable generators in JavaScript.
|
|
608
655
|
|
|
656
|
+
- [Immutable-cursor](https://github.com/redbadger/immutable-cursor)
|
|
657
|
+
- Immutable cursors incorporating the Immutable.js interface over
|
|
658
|
+
Clojure-inspired atom.
|
|
609
659
|
|
|
610
|
-
|
|
611
|
-
|
|
660
|
+
- [Immutable-ext](https://github.com/DrBoolean/immutable-ext)
|
|
661
|
+
- Fantasyland extensions for immutablejs
|
|
612
662
|
|
|
613
|
-
|
|
663
|
+
- [Immutable-js-tools](https://github.com/madeinfree/immutable-js-tools)
|
|
664
|
+
- Util tools for immutable.js
|
|
614
665
|
|
|
666
|
+
- [Immutable-Redux](https://github.com/gajus/redux-immutable)
|
|
667
|
+
- redux-immutable is used to create an equivalent function of Redux
|
|
668
|
+
combineReducers that works with Immutable.js state.
|
|
615
669
|
|
|
616
|
-
|
|
617
|
-
|
|
670
|
+
- [Immutable-Treeutils](https://github.com/lukasbuenger/immutable-treeutils)
|
|
671
|
+
- Functional tree traversal helpers for ImmutableJS data structures.
|
|
618
672
|
|
|
619
|
-
|
|
673
|
+
- [Irecord](https://github.com/ericelliott/irecord)
|
|
674
|
+
- An immutable store that exposes an RxJS observable. Great for React.
|
|
620
675
|
|
|
621
|
-
|
|
676
|
+
- [Mudash](https://github.com/brianneisler/mudash)
|
|
677
|
+
- Lodash wrapper providing Immutable.JS support.
|
|
622
678
|
|
|
679
|
+
- [React-Immutable-PropTypes](https://github.com/HurricaneJames/react-immutable-proptypes)
|
|
680
|
+
- PropType validators that work with Immutable.js.
|
|
623
681
|
|
|
624
|
-
|
|
625
|
-
|
|
682
|
+
- [Redux-Immutablejs](https://github.com/indexiatech/redux-immutablejs)
|
|
683
|
+
- Redux Immutable facilities.
|
|
626
684
|
|
|
627
|
-
|
|
685
|
+
- [Rxstate](https://github.com/yamalight/rxstate)
|
|
686
|
+
- Simple opinionated state management library based on RxJS and Immutable.js.
|
|
628
687
|
|
|
688
|
+
- [Transit-Immutable-js](https://github.com/glenjamin/transit-immutable-js)
|
|
689
|
+
- Transit serialisation for Immutable.js.
|
|
690
|
+
- See also: [Transit-js](https://github.com/cognitect/transit-js)
|
|
629
691
|
|
|
630
|
-
|
|
631
|
-
|
|
692
|
+
Have an additional tool designed to work with Immutable.js?
|
|
693
|
+
Submit a PR to add it to this list in alphabetical order.
|
|
694
|
+
|
|
695
|
+
## Contributing
|
|
696
|
+
|
|
697
|
+
Use [Github issues](https://github.com/immutable-js/immutable-js/issues) for requests.
|
|
698
|
+
|
|
699
|
+
We actively welcome pull requests, learn how to [contribute](https://github.com/immutable-js/immutable-js/blob/main/.github/CONTRIBUTING.md).
|
|
700
|
+
|
|
701
|
+
Immutable.js is maintained within the [Contributor Covenant's Code of Conduct](https://www.contributor-covenant.org/version/2/0/code_of_conduct/).
|
|
702
|
+
|
|
703
|
+
### Changelog
|
|
704
|
+
|
|
705
|
+
Changes are tracked as [Github releases](https://github.com/immutable-js/immutable-js/releases).
|
|
706
|
+
|
|
707
|
+
### License
|
|
708
|
+
|
|
709
|
+
Immutable.js is [MIT-licensed](./LICENSE).
|
|
710
|
+
|
|
711
|
+
### Thanks
|
|
632
712
|
|
|
633
713
|
[Phil Bagwell](https://www.youtube.com/watch?v=K2NYwP90bNs), for his inspiration
|
|
634
714
|
and research in persistent data structures.
|
|
635
715
|
|
|
636
716
|
[Hugh Jackson](https://github.com/hughfdjackson/), for providing the npm package
|
|
637
717
|
name. If you're looking for his unsupported package, see [this repository](https://github.com/hughfdjackson/immutable).
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
License
|
|
641
|
-
-------
|
|
642
|
-
|
|
643
|
-
Immutable.js is [MIT-licensed](https://github.com/facebook/immutable-js/blob/master/LICENSE).
|