UNPKG

11.4 kBJavaScriptView Raw
1"use strict";
2var immutable_1 = require("immutable");
3var log = require('debug')('redux-dag-history:DagGraph');
4var treeify = require('treeify');
5var DagGraph = (function () {
6 function DagGraph(graph) {
7 this.graph = graph;
8 if (!graph) {
9 throw new Error('\'graph\' parameter must be defined');
10 }
11 if (!graph.getIn) {
12 throw new Error('\'graph\' must be an immutablejs instance');
13 }
14 }
15 DagGraph.prototype.print = function () {
16 var _this = this;
17 var graph = this.graph.toJS();
18 var root = null;
19 var states = {};
20 var getOrCreateState = function (stateId) {
21 var result = states[stateId];
22 if (!result) {
23 result = {
24 id: stateId,
25 name: _this.stateName(stateId),
26 children: [],
27 };
28 states[stateId] = result;
29 }
30 return result;
31 };
32 Object.keys(graph.states || {}).forEach(function (stateId) {
33 var parentId = graph.states[stateId].parent;
34 var state = getOrCreateState(stateId);
35 if (!parentId) {
36 root = state;
37 }
38 getOrCreateState(parentId).children.push(state);
39 states[stateId] = state;
40 });
41 var tree = {
42 current: graph.current,
43 branches: graph.branches,
44 dag: root,
45 };
46 var result = treeify.asTree(tree, true);
47 return result;
48 };
49 Object.defineProperty(DagGraph.prototype, "currentStateId", {
50 get: function () {
51 return this.graph.getIn(['current', 'state']);
52 },
53 enumerable: true,
54 configurable: true
55 });
56 DagGraph.prototype.branchStartDepth = function (branch) {
57 return this.stateDepth(this.firstOn(branch));
58 };
59 DagGraph.prototype.branchEndDepth = function (branch) {
60 return this.stateDepth(this.latestOn(branch));
61 };
62 DagGraph.prototype.stateDepth = function (commit) {
63 return this.commitPath(commit).length - 1;
64 };
65 DagGraph.prototype.depthIndexOf = function (branch, commit) {
66 var commits = this.branchCommitPath(branch);
67 var foundIndex = commits.indexOf(commit);
68 if (foundIndex === -1) {
69 return undefined;
70 }
71 else {
72 var start = this.branchStartDepth(branch);
73 return start + foundIndex;
74 }
75 };
76 Object.defineProperty(DagGraph.prototype, "maxDepth", {
77 get: function () {
78 var _this = this;
79 var branches = this.branches;
80 var branchDepths = branches.map(function (b) { return _this.branchEndDepth(b); });
81 var max = -1;
82 branchDepths.forEach(function (d) {
83 if (d > max) {
84 max = d;
85 }
86 });
87 return max;
88 },
89 enumerable: true,
90 configurable: true
91 });
92 DagGraph.prototype.setCurrentStateId = function (stateId) {
93 this.graph = this.graph.setIn(['current', 'state'], stateId);
94 return this;
95 };
96 Object.defineProperty(DagGraph.prototype, "currentBranch", {
97 get: function () {
98 return this.graph.getIn(['current', 'branch']);
99 },
100 enumerable: true,
101 configurable: true
102 });
103 DagGraph.prototype.setCurrentBranch = function (branchId) {
104 this.graph = this.graph.setIn(['current', 'branch'], branchId);
105 return this;
106 };
107 DagGraph.prototype.latestOn = function (branch) {
108 return this.graph.getIn(['branches', "" + branch, 'latest']);
109 };
110 DagGraph.prototype.committedOn = function (branch) {
111 return this.graph.getIn(['branches', "" + branch, 'committed']);
112 };
113 DagGraph.prototype.setLatest = function (branch, commit) {
114 this.graph = this.graph.setIn(['branches', "" + branch, 'latest'], commit);
115 return this;
116 };
117 DagGraph.prototype.setCommitted = function (branch, commit) {
118 this.graph = this.graph.setIn(['branches', "" + branch, 'committed'], commit);
119 return this;
120 };
121 DagGraph.prototype.markStateForBranch = function (commit, branch) {
122 this.graph = this.graph.setIn(['states', "" + commit, 'branch'], branch);
123 return this;
124 };
125 DagGraph.prototype.setFirst = function (branch, commit) {
126 this.graph = this.graph.setIn(['branches', "" + branch, 'first'], commit);
127 return this;
128 };
129 DagGraph.prototype.firstOn = function (branch) {
130 return this.graph.getIn(['branches', "" + branch, 'first']);
131 };
132 DagGraph.prototype.renameState = function (commit, name) {
133 this.graph = this.graph.setIn(['states', "" + commit, 'name'], name);
134 return this;
135 };
136 DagGraph.prototype.stateName = function (commit) {
137 return this.graph.getIn(['states', "" + commit, 'name']);
138 };
139 DagGraph.prototype.getBranchName = function (branch) {
140 return this.graph.getIn(['branches', "" + branch, 'name']);
141 };
142 DagGraph.prototype.setBranchName = function (branch, name) {
143 this.graph = this.graph.setIn(['branches', "" + branch, 'name'], name);
144 return this;
145 };
146 DagGraph.prototype.getState = function (commit) {
147 return this.graph.getIn(['states', "" + commit, 'state']);
148 };
149 DagGraph.prototype.insertState = function (commit, parent, state, name) {
150 log('Inserting new commit', commit);
151 var newState = immutable_1.fromJS({
152 name: name,
153 parent: parent,
154 }).set('state', state);
155 if (this.graph.getIn(['states', "" + commit])) {
156 log('Commit %s is already present', this.getState(commit));
157 }
158 this.graph = this.graph.setIn(['states', "" + commit], newState);
159 return this;
160 };
161 DagGraph.prototype.childrenOf = function (commit) {
162 var states = this.graph.get('states');
163 return states.toSeq()
164 .filter(function (state) { return state.get('parent') === commit; })
165 .map(function (state, key) { return key; })
166 .toList().toJS();
167 };
168 DagGraph.prototype.parentOf = function (commit) {
169 return this.graph.getIn(['states', "" + commit, 'parent']);
170 };
171 DagGraph.prototype.alternateParentsOf = function (commit) {
172 var result = this.graph.getIn(['states', "" + commit, 'alternateParents']);
173 return result ? result.toJS() : [];
174 };
175 DagGraph.prototype.shallowestParentOf = function (commit) {
176 var _this = this;
177 var allParents = [
178 this.parentOf(commit)
179 ].concat(this.alternateParentsOf(commit));
180 var result = undefined;
181 var minDepth = undefined;
182 allParents.forEach(function (t) {
183 var depth = _this.depthIndexOf(_this.branchOf(t), t);
184 if (minDepth === undefined || depth < minDepth) {
185 minDepth = depth;
186 result = t;
187 }
188 });
189 return result;
190 };
191 DagGraph.prototype.replaceState = function (commit, state) {
192 this.graph = this.graph.setIn(['states', "" + commit, 'state'], state);
193 return this;
194 };
195 DagGraph.prototype.commitPath = function (commit) {
196 if (commit === undefined) {
197 return [];
198 }
199 var path = [commit];
200 var current = commit;
201 do {
202 var parent_1 = this.parentOf(current);
203 if (parent_1) {
204 path.unshift(parent_1);
205 }
206 current = parent_1;
207 } while (current);
208 return path;
209 };
210 DagGraph.prototype.shortestCommitPath = function (commit) {
211 if (commit === undefined) {
212 return [];
213 }
214 var path = [commit];
215 var current = commit;
216 do {
217 var parent_2 = this.shallowestParentOf(current);
218 if (parent_2) {
219 path.unshift(parent_2);
220 }
221 current = parent_2;
222 } while (current);
223 return path;
224 };
225 DagGraph.prototype.branchCommitPath = function (branch) {
226 if (branch === undefined) {
227 return [];
228 }
229 var latest = this.latestOn(branch);
230 var path = this.commitPath(latest);
231 var firstCommitOnBranch = this.firstOn(branch);
232 return path.slice(path.indexOf(firstCommitOnBranch));
233 };
234 DagGraph.prototype.setParent = function (commit, parent) {
235 this.graph = this.graph.setIn(['states', "" + commit, 'parent'], parent);
236 };
237 DagGraph.prototype.setAlternateParent = function (commit, parent) {
238 if (this.parentOf(commit) !== parent) {
239 return;
240 }
241 var path = ['states', "" + commit, 'alternateParents'];
242 var parentList = this.graph.getIn(path) ||
243 immutable_1.List();
244 if (!parentList.contains(parent)) {
245 this.graph = this.graph.setIn(path, parentList.push(parent));
246 }
247 };
248 Object.defineProperty(DagGraph.prototype, "branches", {
249 get: function () {
250 var branches = this.graph.get('branches');
251 return Array.from(branches.keys());
252 },
253 enumerable: true,
254 configurable: true
255 });
256 DagGraph.prototype.branchOf = function (commit) {
257 return this.graph.getIn(['states', "" + commit, 'branch']);
258 };
259 DagGraph.prototype.branchesOf = function (commit) {
260 var _this = this;
261 if (!commit) {
262 throw new Error('commit must be defined');
263 }
264 var children = this.childrenOf(commit);
265 if (children.length === 0) {
266 var branches = [];
267 for (var _i = 0, _a = this.branches; _i < _a.length; _i++) {
268 var branch = _a[_i];
269 if (this.latestOn(branch) === commit) {
270 branches.push(branch);
271 }
272 }
273 return branches;
274 }
275 else {
276 var result_1 = [];
277 var childrenBranches = children.map(function (child) { return _this.branchesOf(child); });
278 childrenBranches.forEach(function (cb) { return result_1 = result_1.concat.apply(result_1, cb); });
279 return result_1;
280 }
281 };
282 DagGraph.prototype.remove = function (commit) {
283 this.graph = this.graph.deleteIn(['states', "" + commit]);
284 };
285 DagGraph.prototype.squashCurrentBranch = function () {
286 var _this = this;
287 var toSquash = [];
288 var branch = this.branchOf(this.currentStateId);
289 var current = this.parentOf(this.currentStateId);
290 var keepSquashing = true;
291 do {
292 if (current && this.branchOf(current) === branch) {
293 toSquash.push(current);
294 current = this.parentOf(current);
295 }
296 else {
297 keepSquashing = false;
298 }
299 } while (keepSquashing);
300 log('squashing %s states on branch %s => ', toSquash.length, branch, current, toSquash);
301 if (toSquash.length > 0) {
302 toSquash.forEach(function (c) { return _this.remove(c); });
303 this.setParent(this.currentStateId, current);
304 }
305 return this;
306 };
307 return DagGraph;
308}());
309Object.defineProperty(exports, "__esModule", { value: true });
310exports.default = DagGraph;