All files / packages/tao-utils/src Source.js

93.55% Statements 29/31
94.44% Branches 17/18
80% Functions 8/10
93.55% Lines 29/31
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 756x   4x   10x       3x         11x 6x       6x 10x 2x   9x 2x   5x 5x 2x       4x 2x     5x 4x               8x 8x 8x 10x 8x       8x     8x 4x 2x       6x 2x                        
const DEFAULT_SOURCE = 'FROM';
 
let sourceInstance = 0;
function sourceName(name) {
  return name || `${DEFAULT_SOURCE}${++sourceInstance}`;
}
 
function sourceControl(source) {
  return { source };
}
 
export default class Source {
  constructor(kernel, toSrc, name, fromSrc) {
    if (!kernel || !kernel._network) {
      throw new Error(
        'must provide `kernel` to attach the Source to a network'
      );
    }
    this._network = kernel._network;
    this.forwardAppCtx = (ac, control) => {
      kernel.forwardAppCtx(ac, control);
    };
    if (!toSrc) {
      throw new Error('must provide `toSrc` way to send ACs to the source');
    }
    if (typeof name === 'function') {
      fromSrc = name;
      name = null;
    }
    // Make fromSrc optional for binding a handler
    // if not passed it is a function exposed by the Source i.e. setCtx
    if (fromSrc) {
      Iif (typeof fromSrc !== 'function') {
        throw new Error('optional `fromSrc` must be a function');
      }
      fromSrc((tao, data) =>
        this._network.setCtxControl(
          tao,
          data,
          sourceControl(this.name),
          this.forwardAppCtx
        )
      );
    }
    this._toSrc = toSrc;
    this._name = sourceName(name);
    this._middleware = (handler, ac, fwd, control) =>
      this.handleAppCon(handler, ac, fwd, control);
    this._network.use(this._middleware);
  }
 
  get name() {
    return this._name;
  }
 
  handleAppCon = (handler, ac, forwardAppCtx, control) => {
    if (!control || control.source !== this.name) {
      this._toSrc(ac.unwrapCtx(), ac.data);
    }
  };
 
  setCtx = ({ t, term, a, action, o, orient }, data) => {
    this._network.setCtxControl(
      { t, term, a, action, o, orient },
      data,
      sourceControl(this.name),
      this.forwardAppCtx
    );
  };
 
  dispose() {
    this._network.stop(this._middleware);
  }
}