UI for Zipcoin Blue

task.js 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const chalk_1 = require("chalk");
  4. const format_1 = require("./format");
  5. class Spinner {
  6. constructor(frames = format_1.SPINNER_FRAMES) {
  7. this.frames = frames;
  8. this.i = 0;
  9. }
  10. frame() {
  11. return this.frames[this.i = ++this.i % this.frames.length];
  12. }
  13. }
  14. class Task {
  15. constructor({ msg, log }) {
  16. this.running = false;
  17. this.progressRatio = -1;
  18. this.msg = msg;
  19. this.log = log;
  20. }
  21. start() {
  22. this.running = true;
  23. return this;
  24. }
  25. progress(prog, total) {
  26. this.progressRatio = prog / total;
  27. return this;
  28. }
  29. clear() {
  30. return this;
  31. }
  32. end() {
  33. this.running = false;
  34. this.clear();
  35. return this;
  36. }
  37. succeed() {
  38. if (this.running) {
  39. this.end();
  40. if (this.log.shouldLog('info')) {
  41. this.log.msg(`${chalk_1.default.green(format_1.ICON_SUCCESS)} ${this.msg} - done!`);
  42. }
  43. }
  44. return this;
  45. }
  46. fail() {
  47. if (this.running) {
  48. this.end();
  49. if (this.log.shouldLog('info')) {
  50. this.log.msg(`${chalk_1.default.red(format_1.ICON_FAILURE)} ${this.msg} - failed!`);
  51. }
  52. }
  53. return this;
  54. }
  55. }
  56. class TaskChain {
  57. constructor({ log }) {
  58. this.log = log;
  59. this.tasks = [];
  60. }
  61. next(msg) {
  62. return this._next(new Task({ msg, log: this.log }));
  63. }
  64. _next(task) {
  65. if (this.currentTask) {
  66. this.currentTask.succeed();
  67. }
  68. this.tasks.push(task);
  69. this.currentTask = task;
  70. task.start();
  71. return task;
  72. }
  73. updateMsg(msg) {
  74. if (this.currentTask) {
  75. this.currentTask.msg = msg;
  76. }
  77. return this;
  78. }
  79. end() {
  80. if (this.currentTask) {
  81. this.currentTask.succeed();
  82. this.currentTask = undefined;
  83. }
  84. return this;
  85. }
  86. fail() {
  87. if (this.currentTask) {
  88. this.currentTask.fail();
  89. }
  90. return this;
  91. }
  92. cleanup() {
  93. for (let task of this.tasks) {
  94. if (task.running) {
  95. task.fail();
  96. }
  97. task.clear();
  98. }
  99. return this;
  100. }
  101. }
  102. exports.TaskChain = TaskChain;
  103. class InteractiveTask extends Task {
  104. constructor({ msg, log, bottomBar }) {
  105. super({ msg, log });
  106. this.bottomBar = bottomBar;
  107. this.spinner = new Spinner();
  108. }
  109. start() {
  110. if (!this.running) {
  111. this.intervalId = setInterval(() => { this.tick(); }, 50);
  112. }
  113. super.start();
  114. return this;
  115. }
  116. tick() {
  117. if (this.log.shouldLog('info')) {
  118. this.bottomBar.updateBottomBar(this.format());
  119. }
  120. return this;
  121. }
  122. progress(prog, total) {
  123. super.progress(prog, total);
  124. this.tick();
  125. return this;
  126. }
  127. format() {
  128. const progress = this.progressRatio >= 0 ? (this.progressRatio * 100).toFixed(2) : '';
  129. const frame = this.spinner.frame();
  130. return `${chalk_1.default.bold(frame)} ${this.msg}${progress ? ' (' + chalk_1.default.bold(String(progress) + '%') + ')' : ''} `;
  131. }
  132. clear() {
  133. clearInterval(this.intervalId);
  134. if (this.log.shouldLog('info')) {
  135. this.bottomBar.updateBottomBar('');
  136. }
  137. return this;
  138. }
  139. end() {
  140. this.tick();
  141. super.end();
  142. return this;
  143. }
  144. }
  145. class InteractiveTaskChain extends TaskChain {
  146. constructor({ log, bottomBar }) {
  147. super({ log });
  148. this.bottomBar = bottomBar;
  149. }
  150. next(msg) {
  151. return this._next(new InteractiveTask({ msg, log: this.log, bottomBar: this.bottomBar }));
  152. }
  153. }
  154. exports.InteractiveTaskChain = InteractiveTaskChain;