Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.00 KB | None | 0 0
  1. function fnDoNothing() {}
  2.  
  3. function isClass(func) {
  4. return (
  5. typeof func === 'function' &&
  6. /^class\s/.test(Function.prototype.toString.call(func))
  7. );
  8. }
  9.  
  10. const connect = (stack, fn) => (ctx, next = fnDoNothing) =>
  11. stack(ctx, (nextCtx) => fn(nextCtx, next));
  12.  
  13. class ExecutableNode {
  14. constructor(name, parent = null) {
  15. this._name = name;
  16. this._parent = parent;
  17.  
  18. this._children = {};
  19.  
  20. this.getName = this.getName.bind(this);
  21. this.getFullName = this.getFullName.bind(this);
  22.  
  23. this.isRoot = this.isRoot.bind(this);
  24.  
  25. this._addChild = this._addChild.bind(this);
  26. this.addChild = this.addChild.bind(this);
  27.  
  28. this.use = this.use.bind(this);
  29. this.execute = this.execute.bind(this);
  30.  
  31. this._initGo();
  32. }
  33.  
  34. _initGo() {
  35. if (this._parent) {
  36. this.go = this._parent.go;
  37. } else {
  38. this.go = ((ctx, next = fnDoNothing) => next(ctx)).bind(this);
  39. }
  40. }
  41.  
  42. getName() {
  43. return this._name;
  44. }
  45.  
  46. getFullName() {
  47. if (this.isRoot()) {
  48. return this._name;
  49. }
  50.  
  51. const postfix = '.' + this.getFullName();
  52.  
  53. return this._parent.getFullName() + postfix;
  54. }
  55.  
  56. isRoot() {
  57. return this._parent === null;
  58. }
  59.  
  60. _addChild(child, cb) {
  61. child._parent = this;
  62. this._children[child.getName()] = child;
  63. if (typeof cb === 'function') {
  64. cb(child);
  65. return this;
  66. } else {
  67. return child;
  68. }
  69. }
  70.  
  71. addChild(nameOrChild, cb) {
  72. if (typeof nameOrChild === 'string') {
  73. // name
  74. const child = new ExecutableNode(nameOrChild, this);
  75. return this._addChild(child, cb);
  76. } else {
  77. return this._addChild(nameOrChild, cb);
  78. }
  79. }
  80.  
  81. use(fn) {
  82. this.go = connect(
  83. this.go,
  84. fn.bind(this)
  85. );
  86. return this;
  87. }
  88.  
  89. execute(ctx, fnHandler = fnDoNothing) {
  90. this.go(ctx, (lastCtx) => fnHandler(lastCtx));
  91. }
  92. }
  93.  
  94. class ExceptionGroup extends ExecutableNode {
  95. constructor(name, parent) {
  96. super(name, parent);
  97. this.throw = {};
  98. }
  99.  
  100. addException(name, ctxOrFactoryOrClass, fnHandler = fnDoNothing) {
  101. if (isClass(ctxOrFactoryOrClass)) {
  102. // class
  103. this.throw[name] = (...args) =>
  104. this.execute(new ctxOrFactoryOrClass(...args), fnHandler);
  105. }
  106. if (typeof ctxOrFactoryOrClass === 'function') {
  107. // factory
  108. this.throw[name] = (...args) =>
  109. this.execute(ctxOrFactoryOrClass(...args), fnHandler);
  110. } else {
  111. this.throw[name] = () => this.execute(ctxOrFactoryOrClass, fnHandler);
  112. }
  113. return this;
  114. }
  115.  
  116. addToastException(name, sMessage) {
  117. this.addException(name, null, () => {
  118. // pop toast sMessage
  119. });
  120. }
  121.  
  122. /**
  123. * @callback addGroupCallback
  124. * @param {ExceptionGroup} group - An integer.
  125. */
  126.  
  127. /**
  128. *
  129. * @param {string} name
  130. * @param {addGroupCallback} cb
  131. * @returns {ExceptionGroup}
  132. */
  133. addGroup(name, cb) {
  134. const g = new ExceptionGroup(name, this);
  135. this[name] = g;
  136. return this.addChild(g, cb);
  137. }
  138. }
  139.  
  140. class ExceptionTree extends ExceptionGroup {
  141. constructor(name) {
  142. super(name, null); // tree has no parent
  143. }
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement