dal-engine-core-js-lib-dev 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -40,18 +40,6 @@ class UnknownBehaviorError extends DALEngineError {
40
40
  }
41
41
  }
42
42
 
43
- let ENGINE_TYPES$1 = {
44
- BEHAVIOR: 1,
45
- INVARIANT: 2,
46
- PARTICIPANT: 3,
47
- PRIMITIVE: 4,
48
- BEHAVIORAL_CONTROL_GRAPH: 5,
49
- GRAPH_NODE: 6,
50
- };
51
- ENGINE_TYPES$1 = Object.freeze(ENGINE_TYPES$1);
52
-
53
- var ENGINE_TYPES = ENGINE_TYPES$1;
54
-
55
43
  class MissingAttributes extends DALEngineError {
56
44
  constructor (type, attribute) {
57
45
  let msg;
@@ -64,6 +52,18 @@ class MissingAttributes extends DALEngineError {
64
52
  }
65
53
  }
66
54
 
55
+ let ENGINE_TYPES$1 = {
56
+ BEHAVIOR: 1,
57
+ INVARIANT: 2,
58
+ PARTICIPANT: 3,
59
+ PRIMITIVE: 4,
60
+ BEHAVIORAL_CONTROL_GRAPH: 5,
61
+ GRAPH_NODE: 6,
62
+ };
63
+ ENGINE_TYPES$1 = Object.freeze(ENGINE_TYPES$1);
64
+
65
+ var ENGINE_TYPES = ENGINE_TYPES$1;
66
+
67
67
  /**
68
68
  * Class representing a Invariant in the design.
69
69
  */
@@ -80,9 +80,9 @@ class Invariant extends Base {
80
80
  this.invariantType = null;
81
81
  this.traceId = null;
82
82
  if (typeof args === "object" && Object.hasOwn(args, "uid")) {
83
- this.loadInvariantFromJSON(args);
83
+ this._loadInvariantFromJSON(args);
84
84
  } else {
85
- this.loadArgs(args);
85
+ this._loadArgs(args);
86
86
  }
87
87
  }
88
88
 
@@ -91,7 +91,7 @@ class Invariant extends Base {
91
91
  * @throws {MissingAttributes} Thrown when required attr is not present.
92
92
  * @param {Object} args
93
93
  */
94
- loadArgs (args) {
94
+ _loadArgs (args) {
95
95
  const expectedAttributes = ["name", "rule"];
96
96
  if (typeof args !== "object" || args === null || Array.isArray(args)) {
97
97
  // Not an object, so all attributes are missing.
@@ -109,7 +109,7 @@ class Invariant extends Base {
109
109
  * Loads the participant from a JSON object.
110
110
  * @param {Object} invariantJSON
111
111
  */
112
- loadInvariantFromJSON (invariantJSON) {
112
+ _loadInvariantFromJSON (invariantJSON) {
113
113
  for (const [key, value] of Object.entries(invariantJSON)) {
114
114
  this[key] = value;
115
115
  } // Reset these because they are set by the execution
@@ -196,14 +196,14 @@ class Participant extends Base {
196
196
  */
197
197
  constructor (args) {
198
198
  super();
199
- this.type = ENGINE_TYPES.INVARIANT;
199
+ this.type = ENGINE_TYPES.PARTICIPANT;
200
200
  this.invariants = [];
201
201
  this.abstractionId = null;
202
202
  this.invariantViolated = false;
203
203
  if (typeof args === "object" && Object.hasOwn(args, "uid")) {
204
- this.loadParticipantFromJSON(args);
204
+ this._loadParticipantFromJSON(args);
205
205
  } else {
206
- this.loadArgs(args);
206
+ this._loadArgs(args);
207
207
  }
208
208
  }
209
209
 
@@ -212,7 +212,7 @@ class Participant extends Base {
212
212
  * @throws {MissingAttributes} Thrown when required attr is not present.
213
213
  * @param {Object} args
214
214
  */
215
- loadArgs (args) {
215
+ _loadArgs (args) {
216
216
  const expectedAttributes = ["name"];
217
217
  if (typeof args !== "object" || args === null || Array.isArray(args)) {
218
218
  // Not an object, so all attributes are missing.
@@ -230,7 +230,7 @@ class Participant extends Base {
230
230
  * Loads the participant from a JSON object.
231
231
  * @param {Object} participantJSON
232
232
  */
233
- loadParticipantFromJSON (participantJSON) {
233
+ _loadParticipantFromJSON (participantJSON) {
234
234
  for (const [key, value] of Object.entries(participantJSON)) {
235
235
  if (key === "invariants") {
236
236
  value.forEach(node => this.invariants.push(new Invariant(node)));
@@ -302,9 +302,9 @@ class Behavior extends Base {
302
302
  this.abstractionIds = [];
303
303
  this.invalidWorldState = false;
304
304
  if (typeof args === "object" && Object.hasOwn(args, "uid")) {
305
- this.loadBehaviorFromJSON(args);
305
+ this._loadBehaviorFromJSON(args);
306
306
  } else {
307
- this.loadArgs(args);
307
+ this._loadArgs(args);
308
308
  }
309
309
  }
310
310
 
@@ -313,7 +313,7 @@ class Behavior extends Base {
313
313
  * @throws {MissingAttributes} Thrown when required attr is not present.
314
314
  * @param {Object} args
315
315
  */
316
- loadArgs (args) {
316
+ _loadArgs (args) {
317
317
  const expectedAttributes = ["name"];
318
318
  if (typeof args !== "object" || args === null || Array.isArray(args)) {
319
319
  // Not an object, so all attributes are missing.
@@ -331,7 +331,7 @@ class Behavior extends Base {
331
331
  * Loads the behavior from a JSON object.
332
332
  * @param {Object} behaviorJSON
333
333
  */
334
- loadBehaviorFromJSON (behaviorJSON) {
334
+ _loadBehaviorFromJSON (behaviorJSON) {
335
335
  for (const [key, value] of Object.entries(behaviorJSON)) {
336
336
  if (key === "participants") {
337
337
  value.forEach(node => this.participants.push(new Participant(node)));
@@ -345,7 +345,7 @@ class Behavior extends Base {
345
345
  * @param {Participant} participant
346
346
  * @returns
347
347
  */
348
- addParticpant (participant) {
348
+ addParticipant (participant) {
349
349
  this.participants.push(participant);
350
350
  return participant;
351
351
  }
@@ -385,13 +385,15 @@ class GraphNode extends Base {
385
385
  constructor (args) {
386
386
  super();
387
387
  this.type = ENGINE_TYPES.GRAPH_NODE;
388
- this.goToBehaviorsIds = [];
388
+ this._behavior = null;
389
+ this._goToBehaviorIds = [];
390
+ this._isAtomic = false;
389
391
  if (typeof args === "object" && args !== null) {
390
392
  if (Object.hasOwn(args, "uid")) {
391
- this.loadNodeFromJSON(args);
393
+ this._loadNodeFromJSON(args);
392
394
  } else {
393
- this.behavior = args.behavior;
394
- this.goToBehaviorsIds = args.goToBehaviorsIds;
395
+ this._behavior = args.behavior;
396
+ this._goToBehaviorIds = args.goToBehaviorsIds;
395
397
  }
396
398
  }
397
399
  }
@@ -400,37 +402,87 @@ class GraphNode extends Base {
400
402
  * Loads the nodes from a JSON object.
401
403
  * @param {Object} nodesJSON
402
404
  */
403
- loadNodeFromJSON (nodesJSON) {
405
+ _loadNodeFromJSON (nodesJSON) {
404
406
  for (const [key, value] of Object.entries(nodesJSON)) {
405
407
  if (key === "behavior") {
406
- this.behavior = new Behavior(value);
408
+ this._behavior = new Behavior(value);
407
409
  } else if (key === "goToBehaviorsIds") {
408
- value.forEach(behaviorId => this.goToBehaviorsIds.push(behaviorId));
410
+ value.forEach(behaviorId => this._goToBehaviorIds.push(behaviorId));
409
411
  } else {
410
412
  this[key] = nodesJSON[key];
411
413
  }
412
414
  } }
413
415
 
414
416
  /**
415
- * Adds a behavior name to the list of behaviors that this
417
+ * Returns the behavior of the node.
418
+ * @returns {Behavior|Null}
419
+ */
420
+ getBehavior () {
421
+ return this._behavior;
422
+ }
423
+
424
+ /**
425
+ * Returns the list of behavior names that this node transitions to.
426
+ * @returns {Array}
427
+ */
428
+ getGoToBehaviors () {
429
+ return this._goToBehaviorIds;
430
+ }
431
+
432
+ /**
433
+ * Adds a behavior name to the list of behaviors that this
416
434
  * node transitions to.
417
435
  * @param {String} behaviorId ID of behavior.
418
436
  */
419
437
  addGoToBehavior (behaviorId) {
420
- this.goToBehaviorsIds.push(behaviorId);
438
+ this._goToBehaviorIds.push(behaviorId);
439
+ }
440
+
441
+ /**
442
+ * Adds a behavior name to the list of behaviors that this
443
+ * node transitions to.
444
+ * @param {Array} behaviorIds IDs of behaviors.
445
+ */
446
+ addGoToBehaviors (behaviorIds) {
447
+ this._goToBehaviorIds.push(...behaviorIds);
448
+ }
449
+
450
+ /**
451
+ * Remove the behavior from the list of transitions.
452
+ * @param {String} behaviorId
453
+ */
454
+ removeGoToBehavior (behaviorId) {
455
+ const goToIndex = this._goToBehaviorIds.indexOf(behaviorId);
456
+ if (goToIndex > -1) {
457
+ this._goToBehaviorIds.splice(goToIndex, 1);
458
+ }
459
+ }
460
+
461
+ /**
462
+ * Raises a flag to indicate if the behavior is atomic or not.
463
+ * @param {Boolean} isAtomic Flag indicates if the behavior is atomic.
464
+ */
465
+ setAtomic (isAtomic) {
466
+ this._isAtomic = isAtomic;
467
+ }
468
+
469
+ /**
470
+ * Returns whether the behavior is atomic or not.
471
+ * @returns {Boolean}
472
+ */
473
+ isAtomic () {
474
+ return this._isAtomic;
421
475
  }
422
476
 
423
477
  /**
424
478
  * Checks if the provided behavior name is a valid
425
- * behavior that the control flow selects as a
426
- * result of the this nodes state transformation. i.e.
427
- * is this behavior in the goToBehavior list.
479
+ * transition from this node.
428
480
  * @param {String} behaviorName
429
481
  * @returns {Boolean}
430
482
  */
431
- isValidGoToBehavior (behaviorName) {
432
- for (let i = 0; i < this.goToBehaviorsIds.length; i++) {
433
- const behaviorId = this.goToBehaviorsIds[i];
483
+ isValidTransition (behaviorName) {
484
+ for (let i = 0; i < this._goToBehaviorIds.length; i++) {
485
+ const behaviorId = this._goToBehaviorIds[i];
434
486
  if (behaviorId === behaviorName) {
435
487
  return true;
436
488
  }
@@ -454,7 +506,7 @@ class BehavioralControlGraph extends Base {
454
506
  this.nodes = [];
455
507
  if (typeof args === "object" && args !== null) {
456
508
  if (Object.hasOwn(args, "uid")) {
457
- this.loadGraphFromJSON(args);
509
+ this._loadGraphFromJSON(args);
458
510
  } else {
459
511
  this.name = args.name;
460
512
  }
@@ -465,7 +517,7 @@ class BehavioralControlGraph extends Base {
465
517
  * Loads the graph from a JSON object..
466
518
  * @param {Object} graphJson
467
519
  */
468
- loadGraphFromJSON (graphJson) {
520
+ _loadGraphFromJSON (graphJson) {
469
521
  for (const [key, value] of Object.entries(graphJson)) {
470
522
  if (key === "nodes") {
471
523
  value.forEach(node => this.nodes.push(new GraphNode(node)));
@@ -476,14 +528,16 @@ class BehavioralControlGraph extends Base {
476
528
 
477
529
  /**
478
530
  * Adds a node to the graph.
479
- * @param {Behavior} behavior
531
+ * @param {Behavior} behaviorId
480
532
  * @param {Array} goToBehaviorsIds
533
+ * @param {Boolean} isAtomic
481
534
  * @returns
482
535
  */
483
- addNode (behavior, goToBehaviorsIds) {
536
+ _addNode (behaviorId, goToBehaviorsIds, isAtomic) {
484
537
  const node = new GraphNode({
485
- behavior: behavior,
486
- goToBehaviorsIds: goToBehaviorsIds,
538
+ behavior: new Behavior({name: behaviorId}),
539
+ goToBehaviorsIds: goToBehaviorsIds?goToBehaviorsIds:[],
540
+ isAtomic: isAtomic?isAtomic:false,
487
541
  });
488
542
  this.nodes.push(node);
489
543
  return node;
@@ -497,9 +551,9 @@ class BehavioralControlGraph extends Base {
497
551
  * does not exist in the graph.
498
552
  * @returns
499
553
  */
500
- findNode (behaviorName) {
554
+ _findNode (behaviorName) {
501
555
  for (let i = 0; i < this.nodes.length; i++) {
502
- const behavior = this.nodes[i].behavior;
556
+ const behavior = this.nodes[i].getBehavior();
503
557
  if (behavior.name === behaviorName) {
504
558
  return this.nodes[i];
505
559
  }
@@ -516,8 +570,8 @@ class BehavioralControlGraph extends Base {
516
570
  *
517
571
  * @param {String} behaviorName
518
572
  */
519
- setCurrentBehavior (behaviorName) {
520
- const node = this.findNode(behaviorName);
573
+ _setCurrentBehavior (behaviorName) {
574
+ const node = this._findNode(behaviorName);
521
575
  /**
522
576
  * TODO: Ensure it is atomic because the execution
523
577
  * will only set a behavior when its the first one.
@@ -533,11 +587,11 @@ class BehavioralControlGraph extends Base {
533
587
  * @throws {InvalidTransitionError} Raised when the provided
534
588
  * behavior is not a valid transition.
535
589
  */
536
- goToBehavior (nextBehaviorName) {
537
- if (this.currentNode.isValidGoToBehavior(nextBehaviorName)) {
538
- this.currentNode = this.findNode(nextBehaviorName);
590
+ _goToBehavior (nextBehaviorName) {
591
+ if (this.currentNode.isValidTransition(nextBehaviorName)) {
592
+ this.currentNode = this._findNode(nextBehaviorName);
539
593
  } else {
540
- throw new InvalidTransitionError(this.currentNode.behavior.name, nextBehaviorName);
594
+ throw new InvalidTransitionError(this.currentNode.getBehavior().name, nextBehaviorName);
541
595
  }
542
596
  }
543
597
 
@@ -548,8 +602,8 @@ class BehavioralControlGraph extends Base {
548
602
  exportAsMermaid () {
549
603
  let mermaid = "flowchart TD\n";
550
604
  this.nodes.forEach((node) => {
551
- node.goToBehaviorsIds.forEach((behaviorId) => {
552
- mermaid += ` ${node.behavior.name} --> ${behaviorId}\n`;
605
+ node.getGoToBehaviors().forEach((behaviorId) => {
606
+ mermaid += ` ${node.getBehavior().name} --> ${behaviorId}\n`;
553
607
  });
554
608
  });
555
609
  return mermaid;
@@ -572,6 +626,7 @@ class BehavioralControlGraph extends Base {
572
626
  class DALEngine {
573
627
  constructor (args) {
574
628
  this.graph = new BehavioralControlGraph();
629
+ this.atomicGraphs = [];
575
630
  this.loadArgs(args);
576
631
  }
577
632
 
@@ -607,8 +662,7 @@ class DALEngine {
607
662
  * @param {String} jsonText
608
663
  */
609
664
  deserialize (jsonText) {
610
- this.graph = new BehavioralControlGraph();
611
- this.graph.loadGraphFromJSON(JSON.parse(jsonText));
665
+ this.graph = new BehavioralControlGraph(JSON.parse(jsonText));
612
666
  }
613
667
 
614
668
  /**
@@ -645,34 +699,49 @@ class DALEngine {
645
699
  * @returns {GraphNode}
646
700
  */
647
701
  getNode (behaviorId) {
648
- return this.graph.findNode(behaviorId);
702
+ return this.graph._findNode(behaviorId);
649
703
  }
650
704
 
651
705
  /**
652
706
  * Adds a node to the graph with the given behaviorId and goToBehaviors.
653
707
  * @param {String} behaviorId
654
708
  * @param {Array} goToBehaviorsIds
709
+ * @param {Boolean} isAtomic
655
710
  * @returns {GraphNode}
656
711
  */
657
- addNode (behaviorId, goToBehaviorsIds) {
658
- const behavior = this.createBehavior({name: behaviorId});
659
- return this.graph.addNode(behavior, goToBehaviorsIds);
712
+ addNode (behaviorId, goToBehaviorsIds, isAtomic) {
713
+ return this.graph._addNode(behaviorId, goToBehaviorsIds, isAtomic);
660
714
  }
661
715
 
662
716
  /**
663
- * Adds a goToBehavior to the node with the given behaviorId.
717
+ * Deletes a node from the graph with the given behaviorId and
718
+ * removes it from the goToBehavior list of all other nodes.
664
719
  * @param {String} behaviorId
665
- * @param {String|Array} goToBehaviorIds
666
- * @returns {GraphNode}
667
720
  */
668
- addGoToBehavior (behaviorId, goToBehaviorIds) {
669
- const node = this.graph.findNode(behaviorId);
670
- if (Array.isArray(goToBehaviorIds)) {
671
- node.goToBehaviorsIds.push(...goToBehaviorIds);
672
- } else {
673
- node.goToBehaviorsIds.push(goToBehaviorIds);
721
+ removeNode (behaviorId) {
722
+ const node = this.graph._findNode(behaviorId);
723
+ const nodeIndex = this.graph.nodes.indexOf(node);
724
+ this.graph.nodes.splice(nodeIndex, 1);
725
+ for (const node of this.graph.nodes) {
726
+ node.removeGoToBehavior(behaviorId);
674
727
  }
675
- return node;
728
+ }
729
+
730
+ /**
731
+ * Sets the current behavior in the graph.
732
+ * @param {String} behaviorId
733
+ */
734
+ setCurrentBehavior (behaviorId) {
735
+ this.graph._setCurrentBehavior(behaviorId);
736
+ }
737
+
738
+ /**
739
+ * Transitions the graph to the given behavior if it
740
+ * is a valid transition from the current behavior.
741
+ * @param {String} nextBehaviorId ID of the next behavior.
742
+ */
743
+ goToBehavior (nextBehaviorId) {
744
+ this.graph._goToBehavior(nextBehaviorId);
676
745
  }
677
746
  }
678
747
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dal-engine-core-js-lib-dev",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "main": "dist/index.cjs",
5
5
  "module": "dist/index.esm.js",
6
6
  "type": "module",
@@ -1,6 +1,7 @@
1
1
  import Base from "../Base";
2
2
  import InvalidTransitionError from "../Errors/InvalidTransitionError";
3
3
  import UnknownBehaviorError from "../Errors/UnknownBehaviorError";
4
+ import Behavior from "../Members/Behavior";
4
5
  import ENGINE_TYPES from "../TYPES";
5
6
  import GraphNode from "./GraphNode";
6
7
 
@@ -19,7 +20,7 @@ class BehavioralControlGraph extends Base {
19
20
  this.nodes = [];
20
21
  if (typeof args === "object" && args !== null) {
21
22
  if (Object.hasOwn(args, "uid")) {
22
- this.loadGraphFromJSON(args);
23
+ this._loadGraphFromJSON(args);
23
24
  } else {
24
25
  this.name = args.name;
25
26
  }
@@ -30,7 +31,7 @@ class BehavioralControlGraph extends Base {
30
31
  * Loads the graph from a JSON object..
31
32
  * @param {Object} graphJson
32
33
  */
33
- loadGraphFromJSON (graphJson) {
34
+ _loadGraphFromJSON (graphJson) {
34
35
  for (const [key, value] of Object.entries(graphJson)) {
35
36
  if (key === "nodes") {
36
37
  value.forEach(node => this.nodes.push(new GraphNode(node)));
@@ -42,14 +43,16 @@ class BehavioralControlGraph extends Base {
42
43
 
43
44
  /**
44
45
  * Adds a node to the graph.
45
- * @param {Behavior} behavior
46
+ * @param {Behavior} behaviorId
46
47
  * @param {Array} goToBehaviorsIds
48
+ * @param {Boolean} isAtomic
47
49
  * @returns
48
50
  */
49
- addNode (behavior, goToBehaviorsIds) {
51
+ _addNode (behaviorId, goToBehaviorsIds, isAtomic) {
50
52
  const node = new GraphNode({
51
- behavior: behavior,
52
- goToBehaviorsIds: goToBehaviorsIds,
53
+ behavior: new Behavior({name: behaviorId}),
54
+ goToBehaviorsIds: goToBehaviorsIds?goToBehaviorsIds:[],
55
+ isAtomic: isAtomic?isAtomic:false,
53
56
  });
54
57
  this.nodes.push(node);
55
58
  return node;
@@ -63,9 +66,9 @@ class BehavioralControlGraph extends Base {
63
66
  * does not exist in the graph.
64
67
  * @returns
65
68
  */
66
- findNode (behaviorName) {
69
+ _findNode (behaviorName) {
67
70
  for (let i = 0; i < this.nodes.length; i++) {
68
- const behavior = this.nodes[i].behavior;
71
+ const behavior = this.nodes[i].getBehavior();
69
72
  if (behavior.name === behaviorName) {
70
73
  return this.nodes[i];
71
74
  }
@@ -82,8 +85,8 @@ class BehavioralControlGraph extends Base {
82
85
  *
83
86
  * @param {String} behaviorName
84
87
  */
85
- setCurrentBehavior (behaviorName) {
86
- const node = this.findNode(behaviorName);
88
+ _setCurrentBehavior (behaviorName) {
89
+ const node = this._findNode(behaviorName);
87
90
  /**
88
91
  * TODO: Ensure it is atomic because the execution
89
92
  * will only set a behavior when its the first one.
@@ -99,11 +102,11 @@ class BehavioralControlGraph extends Base {
99
102
  * @throws {InvalidTransitionError} Raised when the provided
100
103
  * behavior is not a valid transition.
101
104
  */
102
- goToBehavior (nextBehaviorName) {
103
- if (this.currentNode.isValidGoToBehavior(nextBehaviorName)) {
104
- this.currentNode = this.findNode(nextBehaviorName);
105
+ _goToBehavior (nextBehaviorName) {
106
+ if (this.currentNode.isValidTransition(nextBehaviorName)) {
107
+ this.currentNode = this._findNode(nextBehaviorName);
105
108
  } else {
106
- throw new InvalidTransitionError(this.currentNode.behavior.name, nextBehaviorName);
109
+ throw new InvalidTransitionError(this.currentNode.getBehavior().name, nextBehaviorName);
107
110
  }
108
111
  }
109
112
 
@@ -114,8 +117,8 @@ class BehavioralControlGraph extends Base {
114
117
  exportAsMermaid () {
115
118
  let mermaid = "flowchart TD\n";
116
119
  this.nodes.forEach((node) => {
117
- node.goToBehaviorsIds.forEach((behaviorId) => {
118
- mermaid += ` ${node.behavior.name} --> ${behaviorId}\n`;
120
+ node.getGoToBehaviors().forEach((behaviorId) => {
121
+ mermaid += ` ${node.getBehavior().name} --> ${behaviorId}\n`;
119
122
  });
120
123
  });
121
124
  return mermaid;
@@ -13,13 +13,15 @@ class GraphNode extends Base {
13
13
  constructor (args) {
14
14
  super();
15
15
  this.type = ENGINE_TYPES.GRAPH_NODE;
16
- this.goToBehaviorsIds = [];
16
+ this._behavior = null;
17
+ this._goToBehaviorIds = [];
18
+ this._isAtomic = false;
17
19
  if (typeof args === "object" && args !== null) {
18
20
  if (Object.hasOwn(args, "uid")) {
19
- this.loadNodeFromJSON(args);
21
+ this._loadNodeFromJSON(args);
20
22
  } else {
21
- this.behavior = args.behavior;
22
- this.goToBehaviorsIds = args.goToBehaviorsIds;
23
+ this._behavior = args.behavior;
24
+ this._goToBehaviorIds = args.goToBehaviorsIds;
23
25
  }
24
26
  }
25
27
  }
@@ -28,12 +30,12 @@ class GraphNode extends Base {
28
30
  * Loads the nodes from a JSON object.
29
31
  * @param {Object} nodesJSON
30
32
  */
31
- loadNodeFromJSON (nodesJSON) {
33
+ _loadNodeFromJSON (nodesJSON) {
32
34
  for (const [key, value] of Object.entries(nodesJSON)) {
33
35
  if (key === "behavior") {
34
- this.behavior = new Behavior(value);
36
+ this._behavior = new Behavior(value);
35
37
  } else if (key === "goToBehaviorsIds") {
36
- value.forEach(behaviorId => this.goToBehaviorsIds.push(behaviorId));
38
+ value.forEach(behaviorId => this._goToBehaviorIds.push(behaviorId));
37
39
  } else {
38
40
  this[key] = nodesJSON[key];
39
41
  }
@@ -41,25 +43,75 @@ class GraphNode extends Base {
41
43
  }
42
44
 
43
45
  /**
44
- * Adds a behavior name to the list of behaviors that this
46
+ * Returns the behavior of the node.
47
+ * @returns {Behavior|Null}
48
+ */
49
+ getBehavior () {
50
+ return this._behavior;
51
+ }
52
+
53
+ /**
54
+ * Returns the list of behavior names that this node transitions to.
55
+ * @returns {Array}
56
+ */
57
+ getGoToBehaviors () {
58
+ return this._goToBehaviorIds;
59
+ }
60
+
61
+ /**
62
+ * Adds a behavior name to the list of behaviors that this
45
63
  * node transitions to.
46
64
  * @param {String} behaviorId ID of behavior.
47
65
  */
48
66
  addGoToBehavior (behaviorId) {
49
- this.goToBehaviorsIds.push(behaviorId);
67
+ this._goToBehaviorIds.push(behaviorId);
68
+ }
69
+
70
+ /**
71
+ * Adds a behavior name to the list of behaviors that this
72
+ * node transitions to.
73
+ * @param {Array} behaviorIds IDs of behaviors.
74
+ */
75
+ addGoToBehaviors (behaviorIds) {
76
+ this._goToBehaviorIds.push(...behaviorIds);
77
+ }
78
+
79
+ /**
80
+ * Remove the behavior from the list of transitions.
81
+ * @param {String} behaviorId
82
+ */
83
+ removeGoToBehavior (behaviorId) {
84
+ const goToIndex = this._goToBehaviorIds.indexOf(behaviorId);
85
+ if (goToIndex > -1) {
86
+ this._goToBehaviorIds.splice(goToIndex, 1);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Raises a flag to indicate if the behavior is atomic or not.
92
+ * @param {Boolean} isAtomic Flag indicates if the behavior is atomic.
93
+ */
94
+ setAtomic (isAtomic) {
95
+ this._isAtomic = isAtomic;
96
+ }
97
+
98
+ /**
99
+ * Returns whether the behavior is atomic or not.
100
+ * @returns {Boolean}
101
+ */
102
+ isAtomic () {
103
+ return this._isAtomic;
50
104
  }
51
105
 
52
106
  /**
53
107
  * Checks if the provided behavior name is a valid
54
- * behavior that the control flow selects as a
55
- * result of the this nodes state transformation. i.e.
56
- * is this behavior in the goToBehavior list.
108
+ * transition from this node.
57
109
  * @param {String} behaviorName
58
110
  * @returns {Boolean}
59
111
  */
60
- isValidGoToBehavior (behaviorName) {
61
- for (let i = 0; i < this.goToBehaviorsIds.length; i++) {
62
- const behaviorId = this.goToBehaviorsIds[i];
112
+ isValidTransition (behaviorName) {
113
+ for (let i = 0; i < this._goToBehaviorIds.length; i++) {
114
+ const behaviorId = this._goToBehaviorIds[i];
63
115
  if (behaviorId === behaviorName) {
64
116
  return true;
65
117
  }
@@ -0,0 +1,35 @@
1
+ import BehavioralControlGraph from "./BehavioralControlGraph";
2
+
3
+ /**
4
+ * Class representing a collection of atomic graphs.
5
+ *
6
+ * These graphs together represent the design. I chose to separate
7
+ * them into their graphs because as the design grows larger, it will
8
+ * be easier to manage the design if it is separated into smaller graphs.
9
+ * It is also easier to visualize in the UI in managable way.
10
+ */
11
+ export class Graphs {
12
+
13
+ constructor () {
14
+ this._graphs = {};
15
+ }
16
+
17
+ /**
18
+ * Adds a graph to the collection of graphs.
19
+ * @param {String} graphId ID of the graph.
20
+ * @returns {BehavioralControlGraph} The graph that was added.
21
+ */
22
+ addGraph (graphId) {
23
+ this._graphs[graphId] = new BehavioralControlGraph();
24
+ return this._graphs[graphId];
25
+ }
26
+
27
+ /**
28
+ * Returns the graph with the given graphId.
29
+ * @param {String} graphId ID of the graph to return.
30
+ * @returns {BehavioralControlGraph} The graph with the given graphId.
31
+ */
32
+ getGraph (graphId) {
33
+ return this._graphs[graphId];
34
+ }
35
+ }