CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/util/immutable-deep-merge.ts
Views: 687
1
/*
2
The immutable.js mergeDeep in immutable 4.1 is badly broken, so we have to implement our own.
3
It used to be fine in 3.8.
4
5
Example in immutable 3.8.2:
6
7
```ts
8
a = require('immutable').fromJS({a:['x','y']})
9
b = require('immutable').fromJS({a:['x','y']})
10
> JSON.stringify(a.mergeDeep(b))
11
'{"a":["x","y"]}'
12
13
// Same in immutable 4.1 has totally different (and very wrong) output:
14
15
> JSON.stringify(a.mergeDeep(b))
16
'{"a":["x","y","x","y"]}'
17
```
18
19
20
It's a documented change at https://immutable-js.com/docs/latest@main/mergeDeep
21
22
"Note: Indexed and set-like collections are merged using concat/union and therefore do not recurse." ARGH!
23
24
Of course we want the result of the above merge to be {"a":["x","y"]}, which is what
25
lodash does (since in Javascript a list is like a map from integers, so the correct semantics
26
are clear).
27
28
Semantics of merge are discussed here: https://stackoverflow.com/questions/19965844/lodash-difference-between-extend-assign-and-merge
29
*/
30
31
import { merge } from "lodash";
32
import { fromJS, Map } from "immutable";
33
34
// This is obviously not a great approach in general, converting back and forth. However, we only
35
// use this for fairly small data in exactly one place, and we can do something the same but more
36
// efficient later.
37
38
export default function mergeDeep(
39
a: Map<string|number|any, any>,
40
b: Map<string|number|any, any>
41
): Map<string|number|any, any> {
42
const c = merge(a.toJS(), b.toJS());
43
return fromJS(c);
44
}
45
46