1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const mobx_1 = require("mobx");
|
5 | const types_1 = require("../notifier/types");
|
6 | const reporter_1 = require("../reporter");
|
7 | const types_2 = require("../types");
|
8 | const dom_1 = require("./dom");
|
9 | const nodes_1 = require("./nodes");
|
10 | const utils_1 = require("./utils");
|
11 | const nanoid = require('nanoid');
|
12 | function createGraph(props) {
|
13 | return new Graph(props);
|
14 | }
|
15 | exports.createGraph = createGraph;
|
16 | class Graph {
|
17 | constructor(props) {
|
18 | this.dom = {
|
19 | nodes: {},
|
20 | nodesByUri: {},
|
21 | nodesByType: {},
|
22 | };
|
23 | this.getNodeById = (id) => {
|
24 | return this.dom.nodes[id];
|
25 | };
|
26 | this.getNodeByUri = (uri) => {
|
27 | return this.dom.nodesByUri[uri];
|
28 | };
|
29 | this.getNodesByType = (type) => {
|
30 | return this.dom.nodesByType[type] || [];
|
31 | };
|
32 | this.processIndexedTree = (tree, parentId) => {
|
33 | for (const item of tree) {
|
34 | const node = this.indexNode({
|
35 | category: nodes_1.NodeCategory.Source,
|
36 | type: item.type,
|
37 | path: item.path,
|
38 | parentId,
|
39 | });
|
40 | if (item.children && item.children.length) {
|
41 | this.processIndexedTree(item.children, node.id);
|
42 | }
|
43 | }
|
44 | };
|
45 | this.id = props.id;
|
46 | this._idGenerator = node => generateNodeId(node, props.idGenerator || exports.defaultIdGenerator, this);
|
47 | this.notifier = props.notifier;
|
48 | }
|
49 | get nodeValues() {
|
50 | return Object.values(this.dom.nodes);
|
51 | }
|
52 | get sourceNodes() {
|
53 | return this.nodeValues.filter(utils_1.isSourceNode);
|
54 | }
|
55 | get virtualNodes() {
|
56 | return this.nodeValues.filter(utils_1.isVirtualNode);
|
57 | }
|
58 | get rootNodes() {
|
59 | return this.sourceNodes.filter(utils_1.isRootNode);
|
60 | }
|
61 | applyPatch(patch) {
|
62 | const patchWithTrace = Object.assign(Object.assign({}, patch), { trace: Object.assign({ instanceId: this.id }, patch.trace) });
|
63 | const eventGroup = this.notifier.createEmitGroup();
|
64 | eventGroup.emit(types_1.GraphiteEvent.DidPatch, patchWithTrace);
|
65 | let result;
|
66 | try {
|
67 | result = dom_1.applyPatch(this.dom, patch, eventGroup);
|
68 | }
|
69 | finally {
|
70 | eventGroup.flush();
|
71 | }
|
72 | return result;
|
73 | }
|
74 | addNode(node, trace, indexOnly = false) {
|
75 | const existingByUri = this.getNodeByPathWithParent(node.path, node.parentId);
|
76 | if (existingByUri)
|
77 | return existingByUri;
|
78 | const id = node.id || this._idGenerator(node);
|
79 | const existingById = this.dom.nodes[id];
|
80 | if (existingById) {
|
81 | reporter_1.reporter.warn(`Warning: addNode() node with id ${id} already exists. It has uri '${existingById.uri}'.`);
|
82 | }
|
83 | this.applyPatch({
|
84 | operations: [
|
85 | {
|
86 | op: dom_1.GraphOp.AddNode,
|
87 | node: Object.assign(Object.assign({}, node), { id }),
|
88 | indexOnly,
|
89 | },
|
90 | ],
|
91 | trace: trace || {
|
92 | instanceId: this.id,
|
93 | },
|
94 | });
|
95 | return this.dom.nodes[id];
|
96 | }
|
97 | indexNode(node, trace) {
|
98 | return this.addNode(node, trace, true);
|
99 | }
|
100 | setSourceNodeDiagnostics(id, source, diagnostics, trace) {
|
101 | this.applyPatch({
|
102 | operations: [
|
103 | {
|
104 | op: dom_1.GraphOp.SetSourceNodeDiagnostics,
|
105 | id,
|
106 | source,
|
107 | diagnostics,
|
108 | },
|
109 | ],
|
110 | trace: trace || {
|
111 | instanceId: this.id,
|
112 | },
|
113 | });
|
114 | }
|
115 | setSourceNodeProp(id, prop, value, trace) {
|
116 | this.applyPatch({
|
117 | operations: [
|
118 | {
|
119 | op: dom_1.GraphOp.SetSourceNodeProp,
|
120 | id,
|
121 | prop,
|
122 | value,
|
123 | },
|
124 | ],
|
125 | trace: trace || {
|
126 | instanceId: this.id,
|
127 | },
|
128 | });
|
129 | }
|
130 | reportError(nodeId, error, trace) {
|
131 | const pluginError = {
|
132 | data: error,
|
133 | message: error.message,
|
134 | nodeId,
|
135 | code: types_2.GraphiteErrorCode.Plugin,
|
136 | trace: trace || {
|
137 | instanceId: this.id,
|
138 | },
|
139 | };
|
140 | reporter_1.reporter.reportError(pluginError);
|
141 | }
|
142 | patchSourceNodeProp(id, prop, value, trace) {
|
143 | this.applyPatch({
|
144 | operations: [
|
145 | {
|
146 | op: dom_1.GraphOp.PatchSourceNodeProp,
|
147 | id,
|
148 | prop,
|
149 | value,
|
150 | },
|
151 | ],
|
152 | trace: trace || {
|
153 | instanceId: this.id,
|
154 | },
|
155 | });
|
156 | }
|
157 | moveNode(id, newParentId, newPath, trace = {}) {
|
158 | this.applyPatch({
|
159 | operations: [
|
160 | {
|
161 | op: dom_1.GraphOp.MoveNode,
|
162 | id,
|
163 | newParentId,
|
164 | newPath,
|
165 | },
|
166 | ],
|
167 | trace,
|
168 | });
|
169 | }
|
170 | removeNode(id, trace) {
|
171 | this.applyPatch({
|
172 | operations: [
|
173 | {
|
174 | op: dom_1.GraphOp.RemoveNode,
|
175 | id,
|
176 | },
|
177 | ],
|
178 | trace: trace || {
|
179 | instanceId: this.id,
|
180 | },
|
181 | });
|
182 | }
|
183 | printTree() {
|
184 | return utils_1.printTree(this.rootNodes);
|
185 | }
|
186 | dehydrate() {
|
187 | return dehydrate(this.dom);
|
188 | }
|
189 | dispose() {
|
190 | }
|
191 | getNodeByPathWithParent(path, parentId) {
|
192 | const parent = parentId && this.getNodeById(parentId);
|
193 | const uri = utils_1.combinePathAndUri(path, parent ? parent.uri : '');
|
194 | return this.getNodeByUri(uri);
|
195 | }
|
196 | }
|
197 | tslib_1.__decorate([
|
198 | mobx_1.computed,
|
199 | tslib_1.__metadata("design:type", Object),
|
200 | tslib_1.__metadata("design:paramtypes", [])
|
201 | ], Graph.prototype, "nodeValues", null);
|
202 | tslib_1.__decorate([
|
203 | mobx_1.computed,
|
204 | tslib_1.__metadata("design:type", Object),
|
205 | tslib_1.__metadata("design:paramtypes", [])
|
206 | ], Graph.prototype, "sourceNodes", null);
|
207 | tslib_1.__decorate([
|
208 | mobx_1.computed,
|
209 | tslib_1.__metadata("design:type", Object),
|
210 | tslib_1.__metadata("design:paramtypes", [])
|
211 | ], Graph.prototype, "virtualNodes", null);
|
212 | tslib_1.__decorate([
|
213 | mobx_1.computed,
|
214 | tslib_1.__metadata("design:type", Object),
|
215 | tslib_1.__metadata("design:paramtypes", [])
|
216 | ], Graph.prototype, "rootNodes", null);
|
217 | tslib_1.__decorate([
|
218 | mobx_1.action.bound,
|
219 | tslib_1.__metadata("design:type", Function),
|
220 | tslib_1.__metadata("design:paramtypes", [Object]),
|
221 | tslib_1.__metadata("design:returntype", void 0)
|
222 | ], Graph.prototype, "applyPatch", null);
|
223 | tslib_1.__decorate([
|
224 | mobx_1.action.bound,
|
225 | tslib_1.__metadata("design:type", Function),
|
226 | tslib_1.__metadata("design:paramtypes", [Object, Object, Boolean]),
|
227 | tslib_1.__metadata("design:returntype", void 0)
|
228 | ], Graph.prototype, "addNode", null);
|
229 | tslib_1.__decorate([
|
230 | mobx_1.action.bound,
|
231 | tslib_1.__metadata("design:type", Function),
|
232 | tslib_1.__metadata("design:paramtypes", [String, String, Object, Object]),
|
233 | tslib_1.__metadata("design:returntype", void 0)
|
234 | ], Graph.prototype, "setSourceNodeProp", null);
|
235 | tslib_1.__decorate([
|
236 | mobx_1.action.bound,
|
237 | tslib_1.__metadata("design:type", Function),
|
238 | tslib_1.__metadata("design:paramtypes", [String, String, Array, Object]),
|
239 | tslib_1.__metadata("design:returntype", void 0)
|
240 | ], Graph.prototype, "patchSourceNodeProp", null);
|
241 | tslib_1.__decorate([
|
242 | mobx_1.action.bound,
|
243 | tslib_1.__metadata("design:type", Function),
|
244 | tslib_1.__metadata("design:paramtypes", [String, Object, String, Object]),
|
245 | tslib_1.__metadata("design:returntype", void 0)
|
246 | ], Graph.prototype, "moveNode", null);
|
247 | tslib_1.__decorate([
|
248 | mobx_1.action.bound,
|
249 | tslib_1.__metadata("design:type", Function),
|
250 | tslib_1.__metadata("design:paramtypes", [String, Object]),
|
251 | tslib_1.__metadata("design:returntype", void 0)
|
252 | ], Graph.prototype, "removeNode", null);
|
253 | exports.addNodeTree = mobx_1.action((helpers, tree, parentId) => {
|
254 | for (const node of tree) {
|
255 | const n = helpers.addNode(Object.assign(Object.assign({}, node), { parentId }));
|
256 | if (node.children && node.children.length) {
|
257 | exports.addNodeTree(helpers, node.children, n.id);
|
258 | }
|
259 | }
|
260 | });
|
261 | exports.defaultIdGenerator = () => nanoid();
|
262 | function generateNodeId(node, idGenerator, nodeFinder) {
|
263 | const parent = node.parentId ? nodeFinder.getNodeById(node.parentId) : void 0;
|
264 | return idGenerator(node, utils_1.combinePathAndUri(node.path, parent ? parent.uri : void 0));
|
265 | }
|
266 | exports.generateNodeId = generateNodeId;
|
267 | function dehydrate(data) {
|
268 | const dehydrated = {
|
269 | nodes: {},
|
270 | };
|
271 | for (const id in data.nodes) {
|
272 | if (!{}.hasOwnProperty.call(data.nodes, id))
|
273 | continue;
|
274 | dehydrated.nodes[id] = data.nodes[id].dehydrate();
|
275 | }
|
276 | return dehydrated;
|
277 | }
|
278 |
|
\ | No newline at end of file |