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