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.cjs +142 -73
- package/dist/index.esm.js +142 -73
- package/package.json +1 -1
- package/src/BehavioralControlGraph/BehavioralControlGraph.js +19 -16
- package/src/BehavioralControlGraph/GraphNode.js +67 -15
- package/src/BehavioralControlGraph/Graphs.js +35 -0
- package/src/DALEngine.js +31 -16
- package/src/Members/Behavior.js +5 -5
- package/src/Members/Invariant.js +4 -4
- package/src/Members/Participant.js +5 -5
- package/tests/DALEngine.test.js +30 -15
- package/tests/Invariant.test.js +5 -5
- package/tests/SimpleDesign.test.js +4 -1
- package/tests/simple_design_temp.json +0 -1
package/dist/index.cjs
CHANGED
|
@@ -42,18 +42,6 @@ class UnknownBehaviorError extends DALEngineError {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
let ENGINE_TYPES = {
|
|
46
|
-
BEHAVIOR: 1,
|
|
47
|
-
INVARIANT: 2,
|
|
48
|
-
PARTICIPANT: 3,
|
|
49
|
-
PRIMITIVE: 4,
|
|
50
|
-
BEHAVIORAL_CONTROL_GRAPH: 5,
|
|
51
|
-
GRAPH_NODE: 6,
|
|
52
|
-
};
|
|
53
|
-
ENGINE_TYPES = Object.freeze(ENGINE_TYPES);
|
|
54
|
-
|
|
55
|
-
var ENGINE_TYPES$1 = ENGINE_TYPES;
|
|
56
|
-
|
|
57
45
|
class MissingAttributes extends DALEngineError {
|
|
58
46
|
constructor (type, attribute) {
|
|
59
47
|
let msg;
|
|
@@ -66,6 +54,18 @@ class MissingAttributes extends DALEngineError {
|
|
|
66
54
|
}
|
|
67
55
|
}
|
|
68
56
|
|
|
57
|
+
let ENGINE_TYPES = {
|
|
58
|
+
BEHAVIOR: 1,
|
|
59
|
+
INVARIANT: 2,
|
|
60
|
+
PARTICIPANT: 3,
|
|
61
|
+
PRIMITIVE: 4,
|
|
62
|
+
BEHAVIORAL_CONTROL_GRAPH: 5,
|
|
63
|
+
GRAPH_NODE: 6,
|
|
64
|
+
};
|
|
65
|
+
ENGINE_TYPES = Object.freeze(ENGINE_TYPES);
|
|
66
|
+
|
|
67
|
+
var ENGINE_TYPES$1 = ENGINE_TYPES;
|
|
68
|
+
|
|
69
69
|
/**
|
|
70
70
|
* Class representing a Invariant in the design.
|
|
71
71
|
*/
|
|
@@ -82,9 +82,9 @@ class Invariant extends Base {
|
|
|
82
82
|
this.invariantType = null;
|
|
83
83
|
this.traceId = null;
|
|
84
84
|
if (typeof args === "object" && Object.hasOwn(args, "uid")) {
|
|
85
|
-
this.
|
|
85
|
+
this._loadInvariantFromJSON(args);
|
|
86
86
|
} else {
|
|
87
|
-
this.
|
|
87
|
+
this._loadArgs(args);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -93,7 +93,7 @@ class Invariant extends Base {
|
|
|
93
93
|
* @throws {MissingAttributes} Thrown when required attr is not present.
|
|
94
94
|
* @param {Object} args
|
|
95
95
|
*/
|
|
96
|
-
|
|
96
|
+
_loadArgs (args) {
|
|
97
97
|
const expectedAttributes = ["name", "rule"];
|
|
98
98
|
if (typeof args !== "object" || args === null || Array.isArray(args)) {
|
|
99
99
|
// Not an object, so all attributes are missing.
|
|
@@ -111,7 +111,7 @@ class Invariant extends Base {
|
|
|
111
111
|
* Loads the participant from a JSON object.
|
|
112
112
|
* @param {Object} invariantJSON
|
|
113
113
|
*/
|
|
114
|
-
|
|
114
|
+
_loadInvariantFromJSON (invariantJSON) {
|
|
115
115
|
for (const [key, value] of Object.entries(invariantJSON)) {
|
|
116
116
|
this[key] = value;
|
|
117
117
|
} // Reset these because they are set by the execution
|
|
@@ -198,14 +198,14 @@ class Participant extends Base {
|
|
|
198
198
|
*/
|
|
199
199
|
constructor (args) {
|
|
200
200
|
super();
|
|
201
|
-
this.type = ENGINE_TYPES$1.
|
|
201
|
+
this.type = ENGINE_TYPES$1.PARTICIPANT;
|
|
202
202
|
this.invariants = [];
|
|
203
203
|
this.abstractionId = null;
|
|
204
204
|
this.invariantViolated = false;
|
|
205
205
|
if (typeof args === "object" && Object.hasOwn(args, "uid")) {
|
|
206
|
-
this.
|
|
206
|
+
this._loadParticipantFromJSON(args);
|
|
207
207
|
} else {
|
|
208
|
-
this.
|
|
208
|
+
this._loadArgs(args);
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
211
|
|
|
@@ -214,7 +214,7 @@ class Participant extends Base {
|
|
|
214
214
|
* @throws {MissingAttributes} Thrown when required attr is not present.
|
|
215
215
|
* @param {Object} args
|
|
216
216
|
*/
|
|
217
|
-
|
|
217
|
+
_loadArgs (args) {
|
|
218
218
|
const expectedAttributes = ["name"];
|
|
219
219
|
if (typeof args !== "object" || args === null || Array.isArray(args)) {
|
|
220
220
|
// Not an object, so all attributes are missing.
|
|
@@ -232,7 +232,7 @@ class Participant extends Base {
|
|
|
232
232
|
* Loads the participant from a JSON object.
|
|
233
233
|
* @param {Object} participantJSON
|
|
234
234
|
*/
|
|
235
|
-
|
|
235
|
+
_loadParticipantFromJSON (participantJSON) {
|
|
236
236
|
for (const [key, value] of Object.entries(participantJSON)) {
|
|
237
237
|
if (key === "invariants") {
|
|
238
238
|
value.forEach(node => this.invariants.push(new Invariant(node)));
|
|
@@ -304,9 +304,9 @@ class Behavior extends Base {
|
|
|
304
304
|
this.abstractionIds = [];
|
|
305
305
|
this.invalidWorldState = false;
|
|
306
306
|
if (typeof args === "object" && Object.hasOwn(args, "uid")) {
|
|
307
|
-
this.
|
|
307
|
+
this._loadBehaviorFromJSON(args);
|
|
308
308
|
} else {
|
|
309
|
-
this.
|
|
309
|
+
this._loadArgs(args);
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
312
|
|
|
@@ -315,7 +315,7 @@ class Behavior extends Base {
|
|
|
315
315
|
* @throws {MissingAttributes} Thrown when required attr is not present.
|
|
316
316
|
* @param {Object} args
|
|
317
317
|
*/
|
|
318
|
-
|
|
318
|
+
_loadArgs (args) {
|
|
319
319
|
const expectedAttributes = ["name"];
|
|
320
320
|
if (typeof args !== "object" || args === null || Array.isArray(args)) {
|
|
321
321
|
// Not an object, so all attributes are missing.
|
|
@@ -333,7 +333,7 @@ class Behavior extends Base {
|
|
|
333
333
|
* Loads the behavior from a JSON object.
|
|
334
334
|
* @param {Object} behaviorJSON
|
|
335
335
|
*/
|
|
336
|
-
|
|
336
|
+
_loadBehaviorFromJSON (behaviorJSON) {
|
|
337
337
|
for (const [key, value] of Object.entries(behaviorJSON)) {
|
|
338
338
|
if (key === "participants") {
|
|
339
339
|
value.forEach(node => this.participants.push(new Participant(node)));
|
|
@@ -347,7 +347,7 @@ class Behavior extends Base {
|
|
|
347
347
|
* @param {Participant} participant
|
|
348
348
|
* @returns
|
|
349
349
|
*/
|
|
350
|
-
|
|
350
|
+
addParticipant (participant) {
|
|
351
351
|
this.participants.push(participant);
|
|
352
352
|
return participant;
|
|
353
353
|
}
|
|
@@ -387,13 +387,15 @@ class GraphNode extends Base {
|
|
|
387
387
|
constructor (args) {
|
|
388
388
|
super();
|
|
389
389
|
this.type = ENGINE_TYPES$1.GRAPH_NODE;
|
|
390
|
-
this.
|
|
390
|
+
this._behavior = null;
|
|
391
|
+
this._goToBehaviorIds = [];
|
|
392
|
+
this._isAtomic = false;
|
|
391
393
|
if (typeof args === "object" && args !== null) {
|
|
392
394
|
if (Object.hasOwn(args, "uid")) {
|
|
393
|
-
this.
|
|
395
|
+
this._loadNodeFromJSON(args);
|
|
394
396
|
} else {
|
|
395
|
-
this.
|
|
396
|
-
this.
|
|
397
|
+
this._behavior = args.behavior;
|
|
398
|
+
this._goToBehaviorIds = args.goToBehaviorsIds;
|
|
397
399
|
}
|
|
398
400
|
}
|
|
399
401
|
}
|
|
@@ -402,37 +404,87 @@ class GraphNode extends Base {
|
|
|
402
404
|
* Loads the nodes from a JSON object.
|
|
403
405
|
* @param {Object} nodesJSON
|
|
404
406
|
*/
|
|
405
|
-
|
|
407
|
+
_loadNodeFromJSON (nodesJSON) {
|
|
406
408
|
for (const [key, value] of Object.entries(nodesJSON)) {
|
|
407
409
|
if (key === "behavior") {
|
|
408
|
-
this.
|
|
410
|
+
this._behavior = new Behavior(value);
|
|
409
411
|
} else if (key === "goToBehaviorsIds") {
|
|
410
|
-
value.forEach(behaviorId => this.
|
|
412
|
+
value.forEach(behaviorId => this._goToBehaviorIds.push(behaviorId));
|
|
411
413
|
} else {
|
|
412
414
|
this[key] = nodesJSON[key];
|
|
413
415
|
}
|
|
414
416
|
} }
|
|
415
417
|
|
|
416
418
|
/**
|
|
417
|
-
*
|
|
419
|
+
* Returns the behavior of the node.
|
|
420
|
+
* @returns {Behavior|Null}
|
|
421
|
+
*/
|
|
422
|
+
getBehavior () {
|
|
423
|
+
return this._behavior;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Returns the list of behavior names that this node transitions to.
|
|
428
|
+
* @returns {Array}
|
|
429
|
+
*/
|
|
430
|
+
getGoToBehaviors () {
|
|
431
|
+
return this._goToBehaviorIds;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Adds a behavior name to the list of behaviors that this
|
|
418
436
|
* node transitions to.
|
|
419
437
|
* @param {String} behaviorId ID of behavior.
|
|
420
438
|
*/
|
|
421
439
|
addGoToBehavior (behaviorId) {
|
|
422
|
-
this.
|
|
440
|
+
this._goToBehaviorIds.push(behaviorId);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Adds a behavior name to the list of behaviors that this
|
|
445
|
+
* node transitions to.
|
|
446
|
+
* @param {Array} behaviorIds IDs of behaviors.
|
|
447
|
+
*/
|
|
448
|
+
addGoToBehaviors (behaviorIds) {
|
|
449
|
+
this._goToBehaviorIds.push(...behaviorIds);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Remove the behavior from the list of transitions.
|
|
454
|
+
* @param {String} behaviorId
|
|
455
|
+
*/
|
|
456
|
+
removeGoToBehavior (behaviorId) {
|
|
457
|
+
const goToIndex = this._goToBehaviorIds.indexOf(behaviorId);
|
|
458
|
+
if (goToIndex > -1) {
|
|
459
|
+
this._goToBehaviorIds.splice(goToIndex, 1);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Raises a flag to indicate if the behavior is atomic or not.
|
|
465
|
+
* @param {Boolean} isAtomic Flag indicates if the behavior is atomic.
|
|
466
|
+
*/
|
|
467
|
+
setAtomic (isAtomic) {
|
|
468
|
+
this._isAtomic = isAtomic;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Returns whether the behavior is atomic or not.
|
|
473
|
+
* @returns {Boolean}
|
|
474
|
+
*/
|
|
475
|
+
isAtomic () {
|
|
476
|
+
return this._isAtomic;
|
|
423
477
|
}
|
|
424
478
|
|
|
425
479
|
/**
|
|
426
480
|
* Checks if the provided behavior name is a valid
|
|
427
|
-
*
|
|
428
|
-
* result of the this nodes state transformation. i.e.
|
|
429
|
-
* is this behavior in the goToBehavior list.
|
|
481
|
+
* transition from this node.
|
|
430
482
|
* @param {String} behaviorName
|
|
431
483
|
* @returns {Boolean}
|
|
432
484
|
*/
|
|
433
|
-
|
|
434
|
-
for (let i = 0; i < this.
|
|
435
|
-
const behaviorId = this.
|
|
485
|
+
isValidTransition (behaviorName) {
|
|
486
|
+
for (let i = 0; i < this._goToBehaviorIds.length; i++) {
|
|
487
|
+
const behaviorId = this._goToBehaviorIds[i];
|
|
436
488
|
if (behaviorId === behaviorName) {
|
|
437
489
|
return true;
|
|
438
490
|
}
|
|
@@ -456,7 +508,7 @@ class BehavioralControlGraph extends Base {
|
|
|
456
508
|
this.nodes = [];
|
|
457
509
|
if (typeof args === "object" && args !== null) {
|
|
458
510
|
if (Object.hasOwn(args, "uid")) {
|
|
459
|
-
this.
|
|
511
|
+
this._loadGraphFromJSON(args);
|
|
460
512
|
} else {
|
|
461
513
|
this.name = args.name;
|
|
462
514
|
}
|
|
@@ -467,7 +519,7 @@ class BehavioralControlGraph extends Base {
|
|
|
467
519
|
* Loads the graph from a JSON object..
|
|
468
520
|
* @param {Object} graphJson
|
|
469
521
|
*/
|
|
470
|
-
|
|
522
|
+
_loadGraphFromJSON (graphJson) {
|
|
471
523
|
for (const [key, value] of Object.entries(graphJson)) {
|
|
472
524
|
if (key === "nodes") {
|
|
473
525
|
value.forEach(node => this.nodes.push(new GraphNode(node)));
|
|
@@ -478,14 +530,16 @@ class BehavioralControlGraph extends Base {
|
|
|
478
530
|
|
|
479
531
|
/**
|
|
480
532
|
* Adds a node to the graph.
|
|
481
|
-
* @param {Behavior}
|
|
533
|
+
* @param {Behavior} behaviorId
|
|
482
534
|
* @param {Array} goToBehaviorsIds
|
|
535
|
+
* @param {Boolean} isAtomic
|
|
483
536
|
* @returns
|
|
484
537
|
*/
|
|
485
|
-
|
|
538
|
+
_addNode (behaviorId, goToBehaviorsIds, isAtomic) {
|
|
486
539
|
const node = new GraphNode({
|
|
487
|
-
behavior:
|
|
488
|
-
goToBehaviorsIds: goToBehaviorsIds,
|
|
540
|
+
behavior: new Behavior({name: behaviorId}),
|
|
541
|
+
goToBehaviorsIds: goToBehaviorsIds?goToBehaviorsIds:[],
|
|
542
|
+
isAtomic: isAtomic?isAtomic:false,
|
|
489
543
|
});
|
|
490
544
|
this.nodes.push(node);
|
|
491
545
|
return node;
|
|
@@ -499,9 +553,9 @@ class BehavioralControlGraph extends Base {
|
|
|
499
553
|
* does not exist in the graph.
|
|
500
554
|
* @returns
|
|
501
555
|
*/
|
|
502
|
-
|
|
556
|
+
_findNode (behaviorName) {
|
|
503
557
|
for (let i = 0; i < this.nodes.length; i++) {
|
|
504
|
-
const behavior = this.nodes[i].
|
|
558
|
+
const behavior = this.nodes[i].getBehavior();
|
|
505
559
|
if (behavior.name === behaviorName) {
|
|
506
560
|
return this.nodes[i];
|
|
507
561
|
}
|
|
@@ -518,8 +572,8 @@ class BehavioralControlGraph extends Base {
|
|
|
518
572
|
*
|
|
519
573
|
* @param {String} behaviorName
|
|
520
574
|
*/
|
|
521
|
-
|
|
522
|
-
const node = this.
|
|
575
|
+
_setCurrentBehavior (behaviorName) {
|
|
576
|
+
const node = this._findNode(behaviorName);
|
|
523
577
|
/**
|
|
524
578
|
* TODO: Ensure it is atomic because the execution
|
|
525
579
|
* will only set a behavior when its the first one.
|
|
@@ -535,11 +589,11 @@ class BehavioralControlGraph extends Base {
|
|
|
535
589
|
* @throws {InvalidTransitionError} Raised when the provided
|
|
536
590
|
* behavior is not a valid transition.
|
|
537
591
|
*/
|
|
538
|
-
|
|
539
|
-
if (this.currentNode.
|
|
540
|
-
this.currentNode = this.
|
|
592
|
+
_goToBehavior (nextBehaviorName) {
|
|
593
|
+
if (this.currentNode.isValidTransition(nextBehaviorName)) {
|
|
594
|
+
this.currentNode = this._findNode(nextBehaviorName);
|
|
541
595
|
} else {
|
|
542
|
-
throw new InvalidTransitionError(this.currentNode.
|
|
596
|
+
throw new InvalidTransitionError(this.currentNode.getBehavior().name, nextBehaviorName);
|
|
543
597
|
}
|
|
544
598
|
}
|
|
545
599
|
|
|
@@ -550,8 +604,8 @@ class BehavioralControlGraph extends Base {
|
|
|
550
604
|
exportAsMermaid () {
|
|
551
605
|
let mermaid = "flowchart TD\n";
|
|
552
606
|
this.nodes.forEach((node) => {
|
|
553
|
-
node.
|
|
554
|
-
mermaid += ` ${node.
|
|
607
|
+
node.getGoToBehaviors().forEach((behaviorId) => {
|
|
608
|
+
mermaid += ` ${node.getBehavior().name} --> ${behaviorId}\n`;
|
|
555
609
|
});
|
|
556
610
|
});
|
|
557
611
|
return mermaid;
|
|
@@ -574,6 +628,7 @@ class BehavioralControlGraph extends Base {
|
|
|
574
628
|
class DALEngine {
|
|
575
629
|
constructor (args) {
|
|
576
630
|
this.graph = new BehavioralControlGraph();
|
|
631
|
+
this.atomicGraphs = [];
|
|
577
632
|
this.loadArgs(args);
|
|
578
633
|
}
|
|
579
634
|
|
|
@@ -609,8 +664,7 @@ class DALEngine {
|
|
|
609
664
|
* @param {String} jsonText
|
|
610
665
|
*/
|
|
611
666
|
deserialize (jsonText) {
|
|
612
|
-
this.graph = new BehavioralControlGraph();
|
|
613
|
-
this.graph.loadGraphFromJSON(JSON.parse(jsonText));
|
|
667
|
+
this.graph = new BehavioralControlGraph(JSON.parse(jsonText));
|
|
614
668
|
}
|
|
615
669
|
|
|
616
670
|
/**
|
|
@@ -647,34 +701,49 @@ class DALEngine {
|
|
|
647
701
|
* @returns {GraphNode}
|
|
648
702
|
*/
|
|
649
703
|
getNode (behaviorId) {
|
|
650
|
-
return this.graph.
|
|
704
|
+
return this.graph._findNode(behaviorId);
|
|
651
705
|
}
|
|
652
706
|
|
|
653
707
|
/**
|
|
654
708
|
* Adds a node to the graph with the given behaviorId and goToBehaviors.
|
|
655
709
|
* @param {String} behaviorId
|
|
656
710
|
* @param {Array} goToBehaviorsIds
|
|
711
|
+
* @param {Boolean} isAtomic
|
|
657
712
|
* @returns {GraphNode}
|
|
658
713
|
*/
|
|
659
|
-
addNode (behaviorId, goToBehaviorsIds) {
|
|
660
|
-
|
|
661
|
-
return this.graph.addNode(behavior, goToBehaviorsIds);
|
|
714
|
+
addNode (behaviorId, goToBehaviorsIds, isAtomic) {
|
|
715
|
+
return this.graph._addNode(behaviorId, goToBehaviorsIds, isAtomic);
|
|
662
716
|
}
|
|
663
717
|
|
|
664
718
|
/**
|
|
665
|
-
*
|
|
719
|
+
* Deletes a node from the graph with the given behaviorId and
|
|
720
|
+
* removes it from the goToBehavior list of all other nodes.
|
|
666
721
|
* @param {String} behaviorId
|
|
667
|
-
* @param {String|Array} goToBehaviorIds
|
|
668
|
-
* @returns {GraphNode}
|
|
669
722
|
*/
|
|
670
|
-
|
|
671
|
-
const node = this.graph.
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
node.
|
|
723
|
+
removeNode (behaviorId) {
|
|
724
|
+
const node = this.graph._findNode(behaviorId);
|
|
725
|
+
const nodeIndex = this.graph.nodes.indexOf(node);
|
|
726
|
+
this.graph.nodes.splice(nodeIndex, 1);
|
|
727
|
+
for (const node of this.graph.nodes) {
|
|
728
|
+
node.removeGoToBehavior(behaviorId);
|
|
676
729
|
}
|
|
677
|
-
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Sets the current behavior in the graph.
|
|
734
|
+
* @param {String} behaviorId
|
|
735
|
+
*/
|
|
736
|
+
setCurrentBehavior (behaviorId) {
|
|
737
|
+
this.graph._setCurrentBehavior(behaviorId);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Transitions the graph to the given behavior if it
|
|
742
|
+
* is a valid transition from the current behavior.
|
|
743
|
+
* @param {String} nextBehaviorId ID of the next behavior.
|
|
744
|
+
*/
|
|
745
|
+
goToBehavior (nextBehaviorId) {
|
|
746
|
+
this.graph._goToBehavior(nextBehaviorId);
|
|
678
747
|
}
|
|
679
748
|
}
|
|
680
749
|
|