-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathcanvasDatasetSelector.ts
60 lines (56 loc) · 2.12 KB
/
canvasDatasetSelector.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import {
DefaultValue,
selector,
} from 'recoil';
import { CanvasDataset } from '../types/CanvasDataset';
import { hasDuplicatedObjects } from '../utils/array';
import { edgesSelector } from './edgesState';
import { nodesSelector } from './nodesState';
/**
* Custom selector for the atom.
*
* Applies custom business logic and sanity check when manipulating the atom.
*/
export const canvasDatasetSelector = selector<CanvasDataset>({
key: 'canvasDatasetSelector',
/**
* Uses the nodes and edges selectors (and not their atoms!) to benefit from their "get" behavior.
* (which handles the default value)
*
* @param get
*/
get: ({ get }): CanvasDataset => {
return {
nodes: get(nodesSelector),
edges: get(edgesSelector),
};
},
/**
* Ensures we don't update neither the nodes nor the edges if there are any duplicates in any of both arrays.
*
* Helps keeping the dataset consistent (integrity), by avoiding updating only the nodes or only the edges if sanity checks don't pass.
*
* XXX It is better to use this selector when updating both edges and nodes at once, to ensure dataset integrity.
* (compared to edgesSelector and nodesSelector which would update each of them on their own,
* and would break dataset integrity if either of them fail to pass the sanity checks)
*
* @param set
* @param get
* @param reset
* @param newValue
*/
set: ({ set, get, reset }, newValue: DefaultValue | CanvasDataset): void => {
const nodes = (newValue as CanvasDataset)?.nodes || [];
const edges = (newValue as CanvasDataset)?.edges || [];
const hasDuplicateNodes = hasDuplicatedObjects(nodes, 'id');
const hasDuplicateEdges = hasDuplicatedObjects(edges, 'id');
if (!hasDuplicateNodes && !hasDuplicateEdges) {
set(nodesSelector, nodes);
set(edgesSelector, edges);
} else {
const message = `Duplicate ids found in "${hasDuplicateNodes ? 'nodes' : ''}" "${hasDuplicateEdges ? 'edges' : ''}", the canvas dataset wasn't updated to avoid to corrupt the dataset.`;
console.error(message, newValue);
throw new Error(message);
}
},
});