@indra.ai/deva 1.2.19 → 1.2.21

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.
Files changed (3) hide show
  1. package/config.json +140 -132
  2. package/index.js +291 -235
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -10,7 +10,7 @@ const { createHash, randomUUID, createCipheriv, createDecipheriv, randomBytes }
10
10
  const config = require('./config.json').DATA // load the deva core configuration data.
11
11
  class Deva {
12
12
  constructor(opts) {
13
- opts = opts || {};
13
+ opts = opts || {}; // set opts to provided opts or an empty object.
14
14
  this._id = randomUUID(); // the unique id assigned to the agent at load
15
15
  this._info = opts.info || false; // the deva information from the package file.
16
16
  this._config = opts.config || {}; // local Config Object
@@ -20,17 +20,9 @@ class Deva {
20
20
  this._security = false; // inherited Security features.
21
21
  this._support = false; // inherited Support features.
22
22
  this._services = false; // inherited Service features.
23
- this.os = require('os'); // It is used to provide basic operating system related utility functions.
24
- this.fs = require('fs'); // this is so file system functions are in the core.
25
- this.path = require('path'); // this is so we can get path in the system.
26
- this.crypto = require('crypto'); // It is used to support cryptography for encryption and decryption.
27
- this.zlib = require('zlib'); // provides compression functionality using Gzip, Deflate/Inflate, and Brotli.
28
- this.dns = require('dns'); // It is used to lookup and resolve on domain names.
29
- this.net = require('net'); // It used to create TCP server/client communicate using TCP protocol.
30
- this.http = require('http'); // It is used to create Http server and Http client.
31
- this.https = require('https'); // It is used to create Http server and Http client.
32
- this.url = require('url'); // It is used for URL resolution and parsing.
33
- this.assert = require('assert'); // It is used for testing itself.
23
+ this.os = os; // It is used to provide basic operating system related utility functions.
24
+ this.fs = fs; // this is so file system functions are in the core.
25
+ this.path = path; // this is so we can get path in the system.
34
26
  this.events = opts.events || new EventEmitter({}); // Event Bus
35
27
  this.libs = opts.libs || {}; // used for loading library functions
36
28
  this.utils = opts.utils || {}; // parse function
@@ -109,7 +101,6 @@ class Deva {
109
101
  return new Promise((resolve, reject) => {
110
102
  try {
111
103
  // set the default listeners for the states of the agent.
112
-
113
104
  for (let state in this._states) {
114
105
  if (typeof this[state] === 'function') {
115
106
  this.events.on(`${this._agent.key}:${state}`, packet => {
@@ -119,15 +110,17 @@ class Deva {
119
110
  }
120
111
 
121
112
  // set the assigned listeners for the agent.
122
- for (let listener in this.listeners) {
123
- this.events.on(listener, packet => {
124
- return this.listeners[listener](packet);
113
+ for (let listener in this.listeners) { // loop over the liteners
114
+ this.events.on(listener, packet => { // set the event listener
115
+ return this.listeners[listener](packet); // return the listener function
125
116
  })
126
117
  }
127
- return resolve();
128
118
  }
129
119
  catch (e) {
130
- return this.error(e, false, reject);
120
+ return this.error(e, false, reject); // pass errors to this.error
121
+ }
122
+ finally {
123
+ return resolve(); // resolve the function after everything is done.
131
124
  }
132
125
  });
133
126
  }
@@ -326,7 +319,6 @@ class Deva {
326
319
  try {
327
320
  delete this._client.features; // delete the features key when done.
328
321
  this.state('ready');
329
- this.action('wait');
330
322
  return resolve(client); // resolve an empty pr
331
323
  } catch (e) {
332
324
  return this.error(e, false, reject);
@@ -351,9 +343,9 @@ class Deva {
351
343
  /**************
352
344
  func: listen
353
345
  params:
354
- - evt: The vent label to listen for
346
+ - evt: The vent label to listen for
355
347
  - callback: The callback function to run when the event fires.
356
- describe:
348
+ describe: setup a new event listener in the system.
357
349
  ***************/
358
350
  listen(evt, callback) {
359
351
  this.listeners[evt] = callback;
@@ -365,8 +357,7 @@ class Deva {
365
357
  /**************
366
358
  func: once
367
359
  params:
368
- - evt: The event to listen to for a once call. These event are handy
369
- when waiting for a key response one time.
360
+ - evt: The event to listen to for a once call.
370
361
  - callback: The callback functoin to run when the event fires.
371
362
  describe:
372
363
  ***************/
@@ -377,10 +368,9 @@ class Deva {
377
368
  /**************
378
369
  func: ignore
379
370
  params:
380
- - evt: The event you'd like to ignore.
371
+ - evt: The event you'd like to ignore.
381
372
  - callback: a callback function to execute after removing the event from listerns.
382
- describe:
383
- The ignore function allow the removal of events that are in the existing devas lister group.
373
+ describe: The ignore function allow the removal of events in the listener group.
384
374
  ***************/
385
375
  ignore(evt, callback) {
386
376
  return this.events.removeListener(evt, callback);
@@ -398,9 +388,10 @@ class Deva {
398
388
  question(TEXT=false, DATA=false) {
399
389
  // check the active status
400
390
  if (!this._active) return Promise.resolve(this._messages.offline);
401
- this.zone('question');
402
- const id = this.uid(); // generate a unique id for transport.
403
- const t_split = TEXT.split(' '); // split the text on spaces to get words.
391
+ this.zone('question'); // set the zone to question.
392
+ const id = this.uid(); // generate a unique id for transport.
393
+ const t_split = TEXT.split(' '); // split the text on spaces to get words.
394
+ const data = DATA; // set the DATA to data
404
395
 
405
396
  // check to see if the string is an #ask string to talk to the other Deva.
406
397
  const isAsk = t_split[0].startsWith(this.askChr);
@@ -408,31 +399,26 @@ class Deva {
408
399
  // check to see if the string is a command string to run a local method.
409
400
  const isCmd = t_split[0].startsWith(this.cmdChr);
410
401
 
411
- this.state('data');
412
402
  // Format the packet for return on the request.
413
- const data = DATA; // set the DATA to data
414
- const packet = { // create the base q/a packet
415
- id, // set the id into packet
416
- q: false, // create empty q object in packet
417
- a: false, // create empty a object in packet
418
- created: Date.now(), // timestamp the packet
403
+ const packet = { // create the base q/a packet
404
+ id, // set the id into packet
405
+ q: false, // create empty q object in packet
406
+ a: false, // create empty a object in packet
407
+ created: Date.now(), // timestamp the packet
419
408
  };
420
409
 
421
- let text = TEXT, // let TEXT is text for a manipulation variable
422
- params = false, // params as false to build params string
423
- method = 'question', // set the default method to question
424
- key = this._agent.key; // set a temporary key from the agent key.
410
+ let text = TEXT, // let TEXT is text for a manipulation variable
411
+ params = false, // params as false to build params string
412
+ method = 'question', // set the default method to question
413
+ key = this._agent.key; // set a temporary key from the agent key.
425
414
 
426
415
  return new Promise((resolve, reject) => {
427
416
  // resolve with the no text message if the client says nothing.
428
417
  if (!TEXT) return this.finish(this._messages.notext, resolve);
429
- // reject question if Deva offline
430
- if (!this._active) return this.finish(this._messages.offline, resolve);
431
- let _action = 'question';
432
- this.state('question');
433
- try { // try to answer the question
434
- if (isAsk) { // determine if hte question isAsk
435
- this.state('ask');
418
+ let _action = 'question'; // set the initial _action to question.
419
+ this.state('question'); // set the state to question
420
+ try { // try to answer the question
421
+ if (isAsk) { // determine if hte question isAsk
436
422
  _action = 'question_ask';
437
423
  // if:isAsk split the agent key and remove first command character
438
424
  key = t_split[0].substring(1);
@@ -440,53 +426,53 @@ class Deva {
440
426
  params = t_split[1] ? t_split[1].split(':') : false;
441
427
  method = params[0]; // the method to check is then params index 0
442
428
  text = t_split.slice(2).join(' ').trim(); // rejoin the text with space
429
+ this.state('ask', `${key} ${method}`);
443
430
  }
444
431
  else if (isCmd) { // determine if the question is a command
445
- this.state('cmd');
446
432
  _action = 'question_cmd';
447
433
  //if:isCmd use text split index 1 as the parameter block
448
434
  params = t_split[0] ? t_split[0].split(':').slice(1) : false;
449
- method = t_split[0].substring(1); // if:isCmd use the 0 index as the command
450
- text = t_split.slice(1).join(' ').trim(); // if:isCmd rejoin the string on the space after removing first index
435
+ method = t_split[0].substring(1); // if:isCmd use the 0 index as the command
436
+ text = t_split.slice(1).join(' ').trim(); // if:isCmd rejoin the string on the space after removing first index
437
+ this.state('cmd', method); // set the state to cmd.
451
438
  }
452
439
 
453
- packet.q = { // build packet.q container
454
- id: this.uid(),
455
- agent: this.agent() || false, // set the agent
456
- client: this.client() || false, // set the client
457
- meta: { // build the meta container
458
- key, // set the key variable
459
- method, // set method to track function use
460
- params, // set any params that are associated
440
+ packet.q = { // build packet.q container
441
+ id: this.uid(), // set the transport id for the question.
442
+ agent: this.agent(), // set the agent
443
+ client: this.client(), // set the client
444
+ meta: { // build the meta container
445
+ key, // set the key variable
446
+ method, // set method to track function use
447
+ params, // set any params that are associated
461
448
  },
462
- text, // set the text for the packet.
463
- data, // set the data object
464
- created: Date.now(), // timestamp the question
449
+ text, // set the text for the packet.
450
+ data, // set the data object
451
+ created: Date.now(), // timestamp the question
465
452
  }
466
453
 
467
454
  // hash the question
468
455
  packet.q.meta.hash = this.hash(packet.q);
469
456
 
470
- this.action(_action);
457
+ this.action(_action, method); // set current action to what was defined by _action variable.
471
458
  this.talk(config.events.question, this.copy(packet)); // global question event make sure to copy data.
472
459
 
473
- if (isAsk) { // isAsk check if the question isAsk and talk
460
+ if (isAsk) { // isAsk check if the question isAsk and talk
474
461
  // if: isAsk wait for the once event which is key'd to the packet ID for specified responses
475
462
  this.talk(`${key}:ask`, packet);
476
463
  this.once(`${key}:ask:${packet.id}`, answer => {
477
464
  this.action('question_ask_answer');
478
-
479
465
  this.talk(config.events.ask, this.copy(answer));
480
- return this.finish(answer, resolve); // if:isAsk resolve the answer from the call
466
+ return this.finish(answer, resolve); // if:isAsk resolve the answer from the call
481
467
  });
482
468
  }
483
- else { // else: answer tue question locally
484
- this.action('question_answer');
469
+ else { // else: answer tue question locally
470
+ this.action('question_answer', method);
485
471
  return this.answer(packet, resolve, reject);
486
472
  }
487
473
  }
488
- catch(e) { // try block error trap
489
- return this.error(e); // if a overall error happens this witll call this.error
474
+ catch(e) {
475
+ return this.error(e); // if a overall error happens this witll call this.error
490
476
  }
491
477
  });
492
478
  }
@@ -503,7 +489,9 @@ class Deva {
503
489
  ***************/
504
490
  answer(packet, resolve, reject) {
505
491
  if (!this._active) return Promise.resolve(this._messages.offline);
506
- this.state('answer');
492
+ this.zone('answer');
493
+ const agent = this.agent();
494
+ const client = this.client();
507
495
  // check if method exists and is of type function
508
496
  const {method,params} = packet.q.meta;
509
497
  const isMethod = this.methods[method] && typeof this.methods[method] == 'function';
@@ -512,7 +500,7 @@ class Deva {
512
500
  }
513
501
  // Call the local method to process the question based the extracted parameters
514
502
  return this.methods[method](packet).then(result => {
515
- this.action('answer');
503
+ this.action('answer', method); // set the action to answer
516
504
  // check the result for the text, html, and data object.
517
505
  // this is for when answers are returned from nested Devas.
518
506
  const text = typeof result === 'object' ? result.text : result;
@@ -520,28 +508,25 @@ class Deva {
520
508
  // if the data passed is NOT an object it will FALSE
521
509
  const data = typeof result === 'object' ? result.data : false;
522
510
 
523
- const agent = this.agent() || false;
524
- const client = this.client() || false;
525
- const packet_answer = { // setup the packet.a container
511
+ const packet_answer = { // setup the packet.a container
526
512
  id: this.uid(),
527
- agent, // set the agent who answered the question
528
- client, // set the client asking the question
529
- meta: { // setup the answer meta container
530
- key: agent.key, // set the agent key inot the meta
531
- method, // set the method into the meta
532
- params, // set the params into the meta
513
+ agent, // set the agent who answered the question
514
+ client, // set the client asking the question
515
+ meta: { // setup the answer meta container
516
+ key: agent.key, // set the agent key inot the meta
517
+ method, // set the method into the meta
518
+ params, // set the params into the meta
533
519
  },
534
- text, // set answer text
535
- html, // set the answer html
536
- data, // set the answer data
537
- created: Date.now(),
520
+ text, // set answer text
521
+ html, // set the answer html
522
+ data, // set the answer data
523
+ created: Date.now(), // set the created date for the answer
538
524
  };
539
525
 
526
+ this.state('answer', method);
540
527
  // create a hash for the answer and insert into answer meta.
541
528
  packet_answer.meta.hash = this.hash(packet_answer);
542
-
543
- packet.a = packet_answer;
544
- this.action('answer_talk');
529
+ packet.a = packet_answer; // set the packet.a to the packet_answer
545
530
  this.talk(config.events.answer, this.copy(packet)); // global talk event
546
531
  return this.finish(packet, resolve); // resolve the packet to the caller.
547
532
  }).catch(err => { // catch any errors in the method
@@ -566,8 +551,8 @@ class Deva {
566
551
  ***************/
567
552
  ask(packet) {
568
553
  if (!this._active) return Promise.resolve(this._messages.offline);
569
-
570
- this.state('ask');
554
+ const {method, params} = packet.q.meta;
555
+ this.zone('ask', method);
571
556
 
572
557
  const agent = this.agent();
573
558
  const client = this.client();
@@ -578,8 +563,8 @@ class Deva {
578
563
  client,
579
564
  meta: {
580
565
  key: agent.key,
581
- method: packet.q.meta.method,
582
- params: packet.q.meta.params,
566
+ method,
567
+ params,
583
568
  },
584
569
  text: false,
585
570
  html: false,
@@ -587,18 +572,18 @@ class Deva {
587
572
  created: Date.now(),
588
573
  };
589
574
 
575
+ this.action('ask', method);
590
576
  try {
591
- if (typeof this.methods[packet.q.meta.method] !== 'function') {
577
+ if (typeof this.methods[method] !== 'function') {
592
578
  return setImmediate(() => {
593
- this.action('invalid')
579
+ this.action('invalid', method);
594
580
  this.talk(`${this._agent.key}:ask:${packet.id}`, this._methodNotFound(packet));
595
581
  });
596
582
  }
597
583
 
598
584
  // The method is parsed and depending on what method is asked for it returns
599
585
  // the response based on the passed through packet.
600
- this.action('ask');
601
- this.methods[packet.q.meta.method](packet).then(result => {
586
+ this.methods[method](packet).then(result => {
602
587
  if (typeof result === 'object') {
603
588
  packet_answer.text = result.text || false;
604
589
  packet_answer.html = result.html || false;
@@ -607,8 +592,9 @@ class Deva {
607
592
  else {
608
593
  packet_answer.text = result;
609
594
  }
595
+
596
+ this.state('ask', method);
610
597
  packet_answer.meta.hash = this.hash(packet_answer);
611
- this.action('ask_answer');
612
598
  packet.a = packet_answer;
613
599
  this.talk(config.events.answer, this.copy(packet)); // global talk event
614
600
  this.talk(`${agent.key}:ask:${packet.id}`, packet);
@@ -644,6 +630,7 @@ class Deva {
644
630
  // set client
645
631
  this._active = Date.now();
646
632
  const agent = this.agent();
633
+
647
634
  const _data = {
648
635
  id: this.uid(true),
649
636
  key: 'init',
@@ -668,7 +655,9 @@ class Deva {
668
655
  }).then(() => {
669
656
  this.zone('init');
670
657
  const hasOnInit = this.onInit && typeof this.onInit === 'function';
671
- return hasOnInit ? this.onInit(_data) : this.start(_data)
658
+ return hasOnInit ? this.onInit(_data) : this.start(_data);
659
+ }).then(done => {
660
+ return resolve(done);
672
661
  }).catch(err => {
673
662
  return this.error(err, client, reject);
674
663
  });
@@ -688,12 +677,12 @@ class Deva {
688
677
  start(data) {
689
678
  this.zone('start');
690
679
  if (!this._active) return Promise.resolve(this._messages.offline);
691
- this.state('start');
680
+ this.action('start');
692
681
  data.value = 'start';
693
682
  delete data.hash;
694
683
  data.hash = this.hash(data);
695
684
  const hasOnStart = this.onStart && typeof this.onStart === 'function' ? true : false;
696
- this.action('start');
685
+ this.state('start');
697
686
  return hasOnStart ? this.onStart(data) : this.enter(data)
698
687
  }
699
688
 
@@ -711,11 +700,11 @@ class Deva {
711
700
  enter(data) {
712
701
  this.zone('enter');
713
702
  if (!this._active) return Promise.resolve(this._messages.offline);
714
- this.state('enter');
703
+ this.action('enter');
715
704
  data.value = 'enter';
716
705
  delete data.hash;
717
706
  data.hash = this.hash(data);
718
- this.action('enter');
707
+ this.state('enter');
719
708
  const hasOnEnter = this.onEnter && typeof this.onEnter === 'function' ? true : false;
720
709
  return hasOnEnter ? this.onEnter(data) : this.done(data)
721
710
  }
@@ -734,12 +723,12 @@ class Deva {
734
723
  done(data) {
735
724
  this.zone('done');
736
725
  if (!this._active) return Promise.resolve(this._messages.offline);
737
- this.state('done');
726
+ this.action('done');
738
727
  data.value = 'done';
739
728
  delete data.hash;
740
729
  data.hash = this.hash(data);
741
730
  const hasOnDone = this.onDone && typeof this.onDone === 'function' ? true : false;
742
- this.action('done')
731
+ this.state('done');
743
732
  return hasOnDone ? this.onDone(data) : Promise.resolve(data);
744
733
  }
745
734
 
@@ -748,21 +737,24 @@ class Deva {
748
737
  params:
749
738
  - packet: the data to pass to the resolve
750
739
  - resolve: the finish resolve to pass back
751
- describe:
752
- This function is use to relay the Agent ito a finish state when resolving a
753
- question or data.
754
- usage:
755
- this.finish(data, resolve)
740
+ describe: This function is use to relay the Agent ito a finish state when
741
+ resolving a question or data.
742
+ usage: this.finish(data, resolve)
756
743
  ***************/
757
744
  finish(packet, resolve) {
758
- this.zone('finish');
745
+ this.zone('finish'); // set the zone to finish
759
746
  if (!this._active) return Promise.resolve(this._messages.offline);
760
- this.state('finish');
747
+
748
+ this.state('finish'); // set the finish state
761
749
  packet.hash = this.hash(packet);// hash the entire packet before finishing.
762
- const hasOnFinish = this.onFinish && typeof this.onFinish === 'function' ? true : false;
750
+ // check for agent on finish function in agent
751
+ const hasOnFinish = this.onFinish && typeof this.onFinish === 'function';
752
+
753
+ this.action('finish'); // set the finish action
754
+ // if: agent has on finish then return on finish
763
755
 
764
756
  if (hasOnFinish) return this.onFinish(packet, resolve);
765
- this.action('finish');
757
+ // return the provided resolve function or a promise resolve.
766
758
  return resolve ? resolve(packet) : Promise.resolve(packet);
767
759
  }
768
760
 
@@ -780,25 +772,21 @@ class Deva {
780
772
  this.stop()
781
773
  ***************/
782
774
  stop() {
783
- this.zone('stop');
775
+ this.zone('stop'); // set the zone to stop
784
776
  if (!this._active) return Promise.resolve(this._messages.offline);
785
-
786
- this.state('stop');
787
- const agent = this.agent();
788
- const client = this.client();
789
-
790
- const data = {
791
- id: this.uid(true),
792
- key: 'stop',
793
- value: this._messages.stop,
794
- agent,
795
- client,
796
- created: Date.now(),
777
+ this.state('stop'); // set the state to stop
778
+ const data = { // build the stop data
779
+ id: this.uid(), // set the id
780
+ agent: this.agent(), // set the agent
781
+ client: this.client(), // set the client
782
+ key: 'stop', // set the key
783
+ value: this._messages.stop, // set the value
784
+ created: Date.now(), // set the created date
797
785
  }
798
- data.hash = this.hash(data);
799
-
800
- this.action('stop');
786
+ this.action('stop'); // set the stop action
787
+ // has stop function then set hasOnStop variable
801
788
  const hasOnStop = this.onStop && typeof this.onStop === 'function';
789
+ // if: has on stop then run on stop function or return exit function.
802
790
  return hasOnStop ? this.onStop(data) : this.exit(data)
803
791
  }
804
792
 
@@ -820,10 +808,10 @@ class Deva {
820
808
  exit() {
821
809
  this.zone('exit');
822
810
 
823
- this.state('exit');
824
811
  const agent = this.agent();
825
812
  const client = this.client();
826
813
 
814
+ this.action('exit');
827
815
  const data = {
828
816
  id: this.uid(true),
829
817
  key: 'exit',
@@ -841,7 +829,7 @@ class Deva {
841
829
  this._support = false;
842
830
  this._services = false;
843
831
 
844
- this.action('exit');
832
+ this.state('exit');
845
833
  const hasOnExit = this.onExit && typeof this.onExit === 'function';
846
834
  return hasOnExit ? this.onExit(data) : Promise.resolve(data)
847
835
  }
@@ -852,27 +840,28 @@ class Deva {
852
840
  /**************
853
841
  func: state
854
842
  params:
855
- - st: The state flag to set for the Deva that matches to this._states
856
- describe
843
+ - value: The state value to set for the Deva that matches to this._states
844
+ - extra: any extra text to add ot the state change.
857
845
  ***************/
858
- state(state) {
846
+ state(value=false, extra=false) {
859
847
  try {
860
- if (!this._states[state]) return;
861
- this._state = state;
862
- const text = this._states[state];
863
- const data = {
864
- id: this.uid(true),
865
- key: 'state',
866
- value: state,
867
- agent: this.agent(),
868
- client: this.client(),
869
- text,
870
- created: Date.now(),
848
+ if (!value || !this._states[value]) return; // return if no matching value
849
+ this._state = value; // set the local state variable.
850
+ const lookup = this._states[value]; // set the local states lookup
851
+ const text = extra ? `${lookup} ${extra}` : lookup; // set text from lookup with extra
852
+ const data = { // build the data object
853
+ id: this.uid(), // set the data id
854
+ agent: this.agent(), // set the agent
855
+ client: this.client(), // set the client
856
+ key: 'state', // set the key to state
857
+ value, // set the value to the passed in value
858
+ text, // set the text value of the data
859
+ created: Date.now(), // set the data created date.
871
860
  };
872
- data.hash = this.hash(data);
873
- this.talk(config.events.state, data);
874
- } catch (e) {
875
- return this.error(e);
861
+ data.hash = this.hash(data); // hash the data
862
+ this.talk(config.events.state, data); // broadcasat the state event
863
+ } catch (e) { // catch any errors
864
+ return this.error(e); // return if an error happens
876
865
  }
877
866
  }
878
867
 
@@ -882,7 +871,8 @@ class Deva {
882
871
  describe: returns the avaiable staets values.
883
872
  ***************/
884
873
  states() {
885
- this.action('states');
874
+ this.action('func', 'states');
875
+ this.state('return', 'states');
886
876
  return {
887
877
  id: this.uid(true),
888
878
  key: 'states',
@@ -897,16 +887,20 @@ class Deva {
897
887
  - st: The zone flag to set for the Deva that matches to this._zones
898
888
  describe
899
889
  ***************/
900
- zone(value) {
901
- if (!this._zones[value] || value === this._zone) return;
890
+ zone(value=false, extra=false) {
891
+ if (!value || !this._zones[value] || value === this._zone) return;
902
892
  try {
903
893
  this._zone = value;
904
- const text = this._zones[value];
905
- const data = {
906
- id: this.uid(true),
894
+
895
+ const lookup = this._zones[value]; // set the lookup value
896
+ const text = extra ? `${lookup} ${extra}` : lookup; // set the text value
897
+
898
+ const data = { // build the zone data
899
+ id: this.uid(), // set the packetid
900
+ agent: this.agent(),
901
+ client: this.client(),
907
902
  key: 'zone',
908
903
  value,
909
- agent: this.agent(),
910
904
  text,
911
905
  created: Date.now(),
912
906
  };
@@ -917,35 +911,47 @@ class Deva {
917
911
  }
918
912
  }
919
913
 
914
+ /**************
915
+ func: zones
916
+ params: none
917
+ describe: returns a listing of zones currently in the system.
918
+ ***************/
920
919
  zones() {
921
- this.action('zones');
920
+ this.action('func', 'zones');
921
+ this.state('return', 'zones');
922
922
  return {
923
- id: this.uid(true),
924
- key: 'zones',
925
- value: this._zones,
926
- created: Date.now(),
923
+ id: this.uid(true), // set the uuid of the data
924
+ agent: this.agent(), // set the agent value
925
+ cleint: this.cleint(), // set the client value
926
+ key: 'zones', // set the key return value
927
+ value: this._zones, // set the list of zones
928
+ created: Date.now(), // set the created date of the object.
927
929
  }
928
930
  }
931
+
929
932
  /**************
930
933
  func: action
931
934
  params:
932
- - st: The state flag to set for the Deva that matches to this._states
935
+ - value: The state flag to set for the Deva that matches to this._states
936
+ - extra: Any extra text to send with the action value.
933
937
  describe
934
938
  ***************/
935
- action(action) {
939
+ action(value=false, extra=false) {
936
940
  try {
937
- this._action = action; // set the local action variable
941
+ if (!value) return; // check feature value
942
+ this._action = value; // set the local action variable
938
943
  // check local vars for custom actions
939
- const var_action = this.vars.actions ? this.vars.actions[action] : false;
940
- // check action messages
941
- const msg_action = this._actions[action] || var_action;
942
- const text = msg_action || action; // set the text of the action
944
+ const var_action = this.vars.actions ? this.vars.actions[value] : false;
945
+ // check the message action
946
+ const msg_action = var_action || this._actions[value];
947
+ const msg = msg_action || action; // set the correct message
948
+ const text = extra ? `${msg} ${extra}` : msg; // set the text of the action
943
949
  const data = { // build the data object for the action.
944
950
  id: this.uid(true), // generate a guid for the action transmitssion.
945
- key: 'action', // the key for event to transmit action type
946
- value: action, // the value key which is the action passed
947
951
  agent: this.agent(), // the agent data to send with the action
948
952
  client: this.client(), // the client data to send with the action
953
+ key: 'action', // the key for event to transmit action type
954
+ value, // the value key which is the action passed
949
955
  text, // text of the action to send
950
956
  created: Date.now(), // action time stamp
951
957
  };
@@ -956,74 +962,96 @@ class Deva {
956
962
  }
957
963
  }
958
964
 
965
+ /**************
966
+ func: actions
967
+ params: none
968
+ describe: Returns a list of available actions in the system.
969
+ ***************/
959
970
  actions() {
960
- this.action('actions');
971
+ this.action('func', 'actions');
972
+ this.state('return', 'actions');
961
973
  return {
962
- id: this.uid(true),
963
- key: 'actions',
964
- value: this._actions,
965
- created: Date.now(),
974
+ id: this.uid(true), // set the id with a uuid
975
+ agent: this.agent(), // set the agent value
976
+ client: this.client(), // set the client value
977
+ key: 'actions', // set the data key
978
+ value: this._actions, // set the value to the actions list
979
+ created: Date.now(), // set the data created date
966
980
  }
967
981
  }
968
982
 
969
983
  /**************
970
984
  func: feature
971
985
  params:
972
- - st: The state flag to set for the Deva that matches to this._states
986
+ - value: The feature flag to set for the Deva that matches to this._features
987
+ - extra: Any extra text to send with the feature value.
973
988
  describe
974
989
  ***************/
975
- feature(feature) {
990
+ feature(value=false, extra=false) {
976
991
  try {
977
- if (!this._features[feature]) return;
978
- this._feature = feature;
979
- const text = this._features[feature] ;
980
- const talk = {
981
- id: this.uid(true),
982
- key: 'feature',
983
- value: feature,
984
- agent: this._agent,
985
- text,
986
- created: Date.now(),
992
+ if (!value || !this._features[value]) return; // check feature value
993
+ this._feature = value; // set local feature variable
994
+
995
+ const lookup = this._features[value]; // set the lookup value
996
+ const text = extra ? `${lookup} ${extra}` : lookup; // set the text value
997
+
998
+ const data = { // build data object
999
+ id: this.uid(true), // set the id
1000
+ agent: this.agent(), // set the agent transporting the packet.
1001
+ key: 'feature', // set the key for transport
1002
+ value, // set the value of the key
1003
+ text, // set the text value
1004
+ created: Date.now(), // set the creation date
987
1005
  };
988
- talk.hash = this.hash(talk);
989
- this.talk(config.events.feature, talk);
990
- } catch (e) {
991
- return this.error(e);
1006
+ data.hash = this.hash(data); // generate the hash value of the data packet
1007
+ this.talk(config.events.feature, data); // talk the feature event with data
1008
+ } catch (e) { // catch any errors
1009
+ return this.error(e); // retun this.error when an error is caught.
992
1010
  }
993
1011
  }
994
1012
 
1013
+ /**************
1014
+ func: features
1015
+ params: none
1016
+ describe: return a list of features that are available to the system.
1017
+ ***************/
995
1018
  features() {
996
- this.action('features');
997
- return {
998
- id: this.uid(true),
999
- key: 'features',
1000
- value: this._features,
1001
- created: Date.now(),
1019
+ this.action('func', 'features');
1020
+ this.state('return', 'features');
1021
+ return { // return the data object
1022
+ id: this.uid(true), // set the object id
1023
+ agent: this.agent(), // set the agent value.
1024
+ client: this.client(), // set the client value.
1025
+ key: 'features', // set the key
1026
+ value: this._features, // set the value to the features list
1027
+ created: Date.now(), // set the created date.
1002
1028
  }
1003
1029
  }
1004
1030
 
1005
1031
  /**************
1006
1032
  func: context
1007
1033
  params:
1008
- - st: The context flag to set for the Deva that matches to this._contexts
1034
+ - value: The context flag to set for the Deva that matches to this._contexts
1035
+ - extra: Any extra text that is sent with the context value.
1009
1036
  describe
1010
1037
  ***************/
1011
1038
  context(value=false, extra=false) {
1012
1039
  try {
1013
- if (!value) return this._context;
1040
+ if (!value) return;
1014
1041
  this._context = value;
1015
1042
  const lookup = this.vars.context[value] || value;
1016
1043
  const text = extra ? `${lookup} ${extra}` : lookup;
1017
1044
 
1018
1045
  const data = {
1019
1046
  id: this.uid(true),
1020
- key: 'context',
1021
- value,
1022
1047
  agent: this.agent(),
1023
1048
  client: this.client(),
1049
+ key: 'context',
1050
+ value,
1024
1051
  text,
1025
1052
  created: Date.now(),
1026
1053
  };
1054
+
1027
1055
  data.hash = this.hash(data);
1028
1056
  this.talk(config.events.context, data);
1029
1057
  } catch (e) {
@@ -1032,9 +1060,12 @@ class Deva {
1032
1060
  }
1033
1061
 
1034
1062
  contexts() {
1035
- this.action('contexts');
1063
+ this.action('func', 'contexts');
1064
+ this.state('return', 'contexts');
1036
1065
  return {
1037
1066
  id: this.uid(true),
1067
+ agent: this.agent(),
1068
+ client: this.client(),
1038
1069
  key: 'contexts',
1039
1070
  value: this.vars.context || false,
1040
1071
  created: Date.now(),
@@ -1044,29 +1075,25 @@ class Deva {
1044
1075
  /**************
1045
1076
  func: client
1046
1077
  params: none
1047
- describe:
1048
- this function allows state management for when client prfioe is
1049
- being accessed.
1078
+ describe: returns the current client values in the system.
1050
1079
  usage: this.client();
1051
1080
  ***************/
1052
1081
  client() {
1053
- if (!this._active) return this._messages.offline; // check the active status
1054
- const client_copy = this.copy(this._client);
1055
- return client_copy; // return the client feature
1082
+ if (!this._active) return this._messages.offline; // check the active status
1083
+ const client_copy = this.copy(this._client); // create a copy of the client data
1084
+ return client_copy; // return the copy of the client data.
1056
1085
  }
1057
1086
 
1058
1087
  /**************
1059
1088
  func: agent
1060
1089
  params: none
1061
- describe:
1062
- this function allows statement management for when client prfioe is
1063
- being accessed.
1090
+ describe: returns the current agent values in the system.
1064
1091
  usage: this.agent()
1065
1092
  ***************/
1066
1093
  agent() {
1067
- if (!this._active) return this._messages.offline;
1068
- const agent_copy = this.copy(this._agent);
1069
- return agent_copy;
1094
+ if (!this._active) return this._messages.offline; // check the active status
1095
+ const agent_copy = this.copy(this._agent); // create a copy of the agent data.
1096
+ return agent_copy; // return the copy of the agent data.
1070
1097
  }
1071
1098
 
1072
1099
  // FEATURE FUNCTIONS
@@ -1077,11 +1104,12 @@ class Deva {
1077
1104
  usage: this.security()
1078
1105
  ***************/
1079
1106
  security() {
1107
+ this.zone('security');
1080
1108
  this.feature('security'); // set the security state
1081
1109
  if (!this._active) return this._messages.offline; // check the active status
1082
- this.state('data'); // set the security state
1110
+ this.action('feature', 'security'); // set the security state
1083
1111
  try {
1084
- this.action('security'); // set the security state
1112
+ this.state('return', 'security'); // set the security state
1085
1113
  return this.copy(this._security); // return the security feature
1086
1114
  } catch (e) {return this.error(e);}
1087
1115
  }
@@ -1093,13 +1121,16 @@ class Deva {
1093
1121
  usage: this.support()
1094
1122
  ***************/
1095
1123
  support() {
1124
+ this.zone('support');
1096
1125
  this.feature('support'); // set the support state
1097
1126
  if (!this._active) return this._messages.offline; // check the active status
1098
- this.state('data');
1127
+ this.action('feature', 'support'); // set the state to data
1099
1128
  try {
1100
- this.action('support');
1129
+ this.state('return', 'support'); // set the action to support.
1101
1130
  return this.copy(this._support); // return the support feature
1102
- } catch (e) {return this.error(e);}
1131
+ } catch (e) {
1132
+ return this.error(e); // return this.error when error catch
1133
+ }
1103
1134
  }
1104
1135
 
1105
1136
  /**************
@@ -1109,13 +1140,16 @@ class Deva {
1109
1140
  usage: this.services()
1110
1141
  ***************/
1111
1142
  services(opts) {
1143
+ this.zone('services');
1112
1144
  this.feature('services'); // set the support state
1113
1145
  if (!this._active) return this._messages.offline; // check the active status
1114
- this.state('data'); // set the services state
1146
+ this.action('feature', 'services'); // set the services state
1115
1147
  try {
1116
- this.action('services'); // set the services state
1148
+ this.state('return', 'services'); // set the services state
1117
1149
  return this.copy(this._services); // return the services feature
1118
- } catch (e) {return this.error(e);}
1150
+ } catch (e) {
1151
+ return this.error(e); // return this.error when error catch
1152
+ }
1119
1153
  }
1120
1154
 
1121
1155
  /**************
@@ -1125,7 +1159,9 @@ class Deva {
1125
1159
  describe: This function will enable fast loading of Deva into the system.
1126
1160
  ***************/
1127
1161
  load(key, client) {
1128
- this.state('load');
1162
+ this.zone('load', key);
1163
+ this.action('load', key);
1164
+ this.state('load', key);
1129
1165
  return this.devas[key].init(client);
1130
1166
  }
1131
1167
 
@@ -1136,13 +1172,15 @@ class Deva {
1136
1172
  describe: Unload a currently loaded Deva.
1137
1173
  ***************/
1138
1174
  unload(key) {
1175
+ this.zone('unload', key);
1139
1176
  return new Promise((resolve, reject) => {
1140
1177
  try {
1141
- this.state('uload');
1178
+ this.action('uload', key);
1142
1179
  this.devas[key].stop().then(exit => {
1143
1180
  delete this.devas[key];
1144
1181
  this.talk(config.events.unload, key);
1145
1182
  });
1183
+ this.state('unload', key)
1146
1184
  return resolve(this._states.unload);
1147
1185
  } catch (e) {
1148
1186
  return this.error(e, this.devas[key], reject)
@@ -1203,6 +1241,7 @@ class Deva {
1203
1241
  defined client security settings.
1204
1242
  ***************/
1205
1243
  cipher(str) {
1244
+ this.feature('cipher');
1206
1245
  // this.action('cipher');
1207
1246
  const security = this._security;
1208
1247
  const {password, algorithm} = security.cipher;
@@ -1213,6 +1252,7 @@ class Deva {
1213
1252
  const _cipher = createCipheriv(algorithm, key_in_bytes, iv);
1214
1253
  const encrypted = _cipher.update(String(str), 'utf8', 'hex') + _cipher.final('hex');
1215
1254
 
1255
+ this.state('return', 'cipher');
1216
1256
  return {
1217
1257
  iv: iv.toString('base64'),
1218
1258
  key,
@@ -1221,6 +1261,7 @@ class Deva {
1221
1261
  }
1222
1262
 
1223
1263
  decipher(opt) {
1264
+ this.feature('decipher');
1224
1265
  // this.action('decipher');
1225
1266
  const iv = Buffer.from(opt.iv, 'base64');
1226
1267
  const encrypted = Buffer.from(opt.encrypted, 'hex');
@@ -1231,6 +1272,7 @@ class Deva {
1231
1272
  const decrypted = decipher.update(encrypted);
1232
1273
  const final = Buffer.concat([decrypted, decipher.final()]);
1233
1274
  return final.toString();
1275
+ this.state('return', 'decipher');
1234
1276
  }
1235
1277
 
1236
1278
  /**************
@@ -1243,7 +1285,7 @@ class Deva {
1243
1285
  usage: this.prompt('text')
1244
1286
  ***************/
1245
1287
  prompt(text) {
1246
- this.action('prompt');
1288
+ this.feature('prompt');
1247
1289
  // Talk a global prompt event for the client
1248
1290
  const agent = this.agent();
1249
1291
  const client = this.client();
@@ -1256,6 +1298,7 @@ class Deva {
1256
1298
  text,
1257
1299
  created: Date.now(),
1258
1300
  }
1301
+ this.state('talk', 'prompt')
1259
1302
  return this.talk(config.events.prompt, _data);
1260
1303
  }
1261
1304
 
@@ -1283,13 +1326,14 @@ class Deva {
1283
1326
  with no time value for the current day.
1284
1327
  ***************/
1285
1328
  getToday(d) {
1286
- this.action('gettoday');
1329
+ this.feature('getToday');
1287
1330
  d = d ? d : Date.now();
1288
1331
  const today = new Date(d);
1289
1332
  today.setHours(0);
1290
1333
  today.setMinutes(0);
1291
1334
  today.setSeconds(0);
1292
1335
  today.setMilliseconds(0);
1336
+ this.state('return', 'getToday');
1293
1337
  return today.getTime();
1294
1338
  }
1295
1339
 
@@ -1306,6 +1350,7 @@ class Deva {
1306
1350
  system based on the language and locale in the client profile.
1307
1351
  ***************/
1308
1352
  formatDate(d, format='milli', time=false) {
1353
+ this.feature('formatDate');
1309
1354
  if (!d) d = Date.now();
1310
1355
  d = new Date(d);
1311
1356
 
@@ -1324,6 +1369,7 @@ class Deva {
1324
1369
  };
1325
1370
  const theDate = d.toLocaleDateString(this._client.locale, formats[format]);
1326
1371
  const theTime = this.formatTime(d);
1372
+ this.state('return', 'formatDate');
1327
1373
  return !theTime ? theDate : `${theDate} - ${theTime}`;
1328
1374
  }
1329
1375
 
@@ -1336,6 +1382,7 @@ class Deva {
1336
1382
  parameter based on the locale setting in the client profile..
1337
1383
  ***************/
1338
1384
  formatTime(t) {
1385
+ this.feature('formatTime');
1339
1386
  return t.toLocaleTimeString(this._client.locale); // return the formatted time string
1340
1387
  }
1341
1388
 
@@ -1348,6 +1395,7 @@ class Deva {
1348
1395
  in the client profile.
1349
1396
  ***************/
1350
1397
  formatCurrency(n) {
1398
+ this.feature('formatCurrency');
1351
1399
  return new Intl.NumberFormat(this._client.locale, { style: 'currency', currency: this._client.currency }).format(n);
1352
1400
  }
1353
1401
 
@@ -1359,6 +1407,7 @@ class Deva {
1359
1407
  describe:
1360
1408
  ***************/
1361
1409
  formatPercent(n, dec=2) {
1410
+ this.feature('formatPercent');
1362
1411
  return parseFloat(n).toFixed(dec) + '%';
1363
1412
  }
1364
1413
 
@@ -1371,8 +1420,10 @@ class Deva {
1371
1420
  A utility function to trimText intput to a specific word count.
1372
1421
  ***************/
1373
1422
  trimWords(text, maxwords) {
1423
+ this.feature('trimWords');
1374
1424
  const splitter = text.split(' ');
1375
1425
  if (splitter < maxwords) return text;
1426
+ this.state('return', 'trimmed words');
1376
1427
  return splitter.slice(0, maxwords).join(' ');
1377
1428
  }
1378
1429
 
@@ -1382,9 +1433,10 @@ class Deva {
1382
1433
  describe: remove duplicees from an array.
1383
1434
  ***************/
1384
1435
  dupes(dupers) {
1385
- this.action('dupes');
1436
+ this.feature('dupes');
1386
1437
  if (!Array.isArray(dupers)) return dupers;
1387
1438
  const check = [];
1439
+ this.state('return', 'duplicates removed');
1388
1440
  return dupers.filter(dupe => {
1389
1441
  if (!check.includes(dupe)) {
1390
1442
  check.push(dupe);
@@ -1401,7 +1453,7 @@ class Deva {
1401
1453
  info() {
1402
1454
  // check the active status
1403
1455
  if (!this._active) return Promise.resolve(this._messages.offline);
1404
- this.action('info');
1456
+ this.feature('info');
1405
1457
  return this._info;
1406
1458
  }
1407
1459
 
@@ -1418,11 +1470,12 @@ class Deva {
1418
1470
  ***************/
1419
1471
  status(msg=false) {
1420
1472
  // check the active status
1421
- if (!this._active) return Promise.resolve(this._messages.states.offline);
1473
+ if (!this._active) return Promise.resolve(this._messages.offline);
1474
+ this.feature('status');
1475
+
1422
1476
  // format the date since active for output.
1423
1477
  const dateFormat = this.formatDate(this._active, 'long', true);
1424
1478
  // create the text msg string
1425
- this.action('status');
1426
1479
  let text = `${this._agent.profile.name} active since ${dateFormat}`;
1427
1480
  if (msg) text = text + `\n${msg}`; // append the msg string if msg true.
1428
1481
  return text; // return final text string
@@ -1439,19 +1492,21 @@ class Deva {
1439
1492
  one exists it will then present it based on the users request text input.
1440
1493
  ***************/
1441
1494
  help(msg, help_dir) {
1442
- this.zone('help');
1443
1495
  return new Promise((resolve, reject) => {
1444
- if (!this._active) return resolve(this._messages.states.offline);
1445
- this.state('data');
1496
+ if (!this._active) return resolve(this._messages.offline);
1497
+ this.feature('help');
1498
+ this.zone('help');
1499
+
1446
1500
  const params = msg.split(' ');
1447
1501
  let helpFile = 'main';
1448
1502
  if (params[0]) helpFile = params[0];
1449
1503
  if (params[1]) helpFile = `${params[0]}_${params[1]}`;
1450
1504
  helpFile = path.join(help_dir, 'help', `${helpFile}.feecting`);
1451
1505
  try {
1452
- this.action('help');
1506
+ this.state('resolve', 'help');
1453
1507
  return resolve(fs.readFileSync(helpFile, 'utf8'));
1454
1508
  } catch (e) {
1509
+ this.state('reject', 'helpFile');
1455
1510
  return reject(e)
1456
1511
  }
1457
1512
  });
@@ -1470,7 +1525,7 @@ class Deva {
1470
1525
  error(err,data=false,reject=false) {
1471
1526
  this.zone('error');
1472
1527
 
1473
- this.state('error')
1528
+ this.action('error')
1474
1529
  const agent = this.agent();
1475
1530
  const client = this.client();
1476
1531
  const _data = {
@@ -1485,7 +1540,8 @@ class Deva {
1485
1540
  }
1486
1541
  this.talk(config.events.error, this.copy(_data));
1487
1542
  const hasOnError = this.onError && typeof this.onError === 'function' ? true : false;
1488
- this.action('error');
1543
+
1544
+ this.state('error');
1489
1545
  if (hasOnError) return this.onError(err, data, reject);
1490
1546
  else return reject ? reject(err) : err;
1491
1547
  }