{"size": 1438, "ext": "js", "max_stars_repo_path": "src/functions/subject.js", "max_stars_repo_name": "frptools/propagate", "max_stars_repo_stars_event_min_datetime": "2018-02-02T23:39:15.000Z", "max_stars_repo_stars_event_max_datetime": "2020-09-08T07:43:43.000Z", "max_issues_repo_path": "src/functions/subject.js", "max_issues_repo_name": "frptools/propagate", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "src/functions/subject.js", "max_forks_repo_name": "frptools/propagate", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 7, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 21.7878787879, "max_line_length": 71, "alphanum_fraction": 0.6043115438}
import * as F from '@frptools/corelib';
import { Signal, SignalInput, Signaller, SIGNAL_VALUE } from '../core';

export function value (value, source) {
  return new SubjectSignal(value, source);
}

export class SubjectSignal extends Signal {
  constructor (value, source) {
    super();

    this[SIGNAL_VALUE] = value;
    this._signaller = new Signaller();
    this._source = source;
  }

  _set (value, signaller) {
    if (this[SIGNAL_VALUE] === value) {
      return false;
    }
    this[SIGNAL_VALUE] = value;
    signaller.add(this);
    return true;
  }

  get value () {
    return this[SIGNAL_VALUE];
  }

  set value (value) {
    const signaller = this._signaller;
    if (this._set(value, this._signaller)) {
      signaller.next();
    }
  }

  recompute () {
    return true;
  }

  set (value, signaller) {
    const defer = signaller instanceof Signaller;
    const s = defer ? signaller : this._signaller;
    if (this._set(value, s) && !defer) {
      s.next();
    }
  }

  connect (output, ref) {
    if (!this.active && F.isDefined(this._source)) {
      setTimeout(() => {
        const input = new SignalInput(this._source, this);
        this.inputs.push(input);
        this.refs.connect(input);
      }, 1);
    }
    super.connect(output, ref);
  }

  disconnect (output, ref) {
    super.disconnect(output, ref);
    if (F.isDefined(this._source) && !this.active) {
      this.inputs.length = 0;
    }
  }
}