/
seer-integration.js
135 lines (110 loc) · 2.84 KB
/
seer-integration.js
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import seer from 'seer';
/**
* Recursively set a nested property of an object given a properties array and a value
*/
const recursiveSet = (obj, path, value) => {
if (!obj) {
return;
}
if (path.length > 1) {
recursiveSet(obj[path[0]], path.slice(1), value);
} else {
obj[path[0]] = value;
}
};
const overrides = new Map();
/**
* Create an override on the specify layer, indexed by a valuePath array.
* Do nothing in case Seer as not been initialized to prevent any preformance drawback.
*/
export const setPropOverrides = (id, valuePath, value) => {
if (!seer.isReady()) {
return;
}
if (!overrides.has(id)) {
overrides.set(id, new Map());
}
const props = overrides.get(id);
props.set(valuePath, value);
};
/**
* Get the props overrides of a specific layer if Seer as been initialized
* Invalidates the data to be sure new ones are always picked up.
*/
export const applyPropOverrides = props => {
if (!seer.isReady() || !props.id) {
return;
}
const overs = overrides.get(props.id);
if (!overs) {
return;
}
overs.forEach((value, valuePath) => {
recursiveSet(props, valuePath, value);
// Invalidate data array if we have a data override
if (valuePath[0] === 'data') {
props.data = [...props.data];
}
});
};
/**
* Listen for deck.gl edit events
*/
export const layerEditListener = cb => {
if (!seer.isReady()) {
return;
}
seer.listenFor('deck.gl', cb);
};
/**
* Listen for seer init events to resend data
*/
export const seerInitListener = cb => {
if (!seer.isReady()) {
return;
}
seer.listenFor('init', cb);
};
export const initLayerInSeer = layer => {
if (!seer.isReady() || !layer) {
return;
}
const badges = [layer.constructor.layerName];
seer.listItem('deck.gl', layer.id, {
badges,
// TODO: Seer currently only handles single model layers
links: layer.state && layer.state.model ? [`luma.gl:${layer.state.model.id}`] : undefined,
parent: layer.parent ? layer.parent.id : undefined
});
};
/**
* Log layer's properties to Seer
*/
export const updateLayerInSeer = layer => {
if (!seer.isReady() || seer.throttle(`deck.gl:${layer.id}`, 1e3)) {
return;
}
const data = logPayload(layer);
seer.multiUpdate('deck.gl', layer.id, data);
};
/**
* On finalize of a specify layer, remove it from seer
*/
export const removeLayerInSeer = id => {
if (!seer.isReady() || !id) {
return;
}
seer.deleteItem('deck.gl', id);
};
function logPayload(layer) {
const data = [{path: 'objects.props', data: layer.props}];
const badges = [layer.constructor.layerName];
if (layer.state) {
if (layer.getAttributeManager()) {
const attrs = layer.getAttributeManager().getAttributes();
data.push({path: 'objects.attributes', data: attrs});
}
}
data.push({path: 'badges', data: badges});
return data;
}