JSFiddle - React, Tailwind, and code Playground

by joplomacedo

JavaScript

class Subject {
  constructor(initialVal) {
    this.subscriptions = [];
    this.onCompleteCbs = [];
    this.values = [];

    if (initialVal) {
      this.values.push(initialVal);
    }
  }

  next(val) {
    this.values.push(val);

    this.subscriptions.forEach(subscription => {
      if ( subscription ) {
        const res = subscription.next(val);

        if ( res === false ) {
          subscription.unsubscribe();
        }
      }
    });
  }

  complete() {
    this.isComplete = true;
    this.subscriptions.forEach(item => item && item.complete());
    this.onCompleteCbs.forEach(cb => cb());

    this.complete = () => {};
    this.next = () => {};
    this.parentSubscription && this.parentSubscription.unsubscribe();
  }

  subscribe(cbs, immediate) {
    let subscription = {
      idx: this.subscriptions.length,
      unsubscribe: () => {
        delete this.subscriptions[subscription.idx];
      }
    };

    if (typeof cbs === "function") {
      subscription.next = cbs;
      subscription.error = () => { };
      subscription.complete = () => { };
    } else {
      subscription.next = cbs.next || (() => { });
      subscription.error = cbs.error || (() => { });
      subscription.complete = cbs.complete || (() => { });
    }

    this.subscriptions.push(subscription);

    if (immediate && this.values.length) {
      subscription.next(this.getValue());
    }

    return {
      unsubscribe: subscription.unsubscribe
    };
  }

  getValue() {
    return this.values[this.values.length - 1];
  }

  _pipe({ subject, val, fns }) {
    let isNextCalled = false;
    let isCompleteCalled = false;
    let currVal = val;

    for ( let f of fns ) {
        isNextCalled = false;

        f({
            val: currVal,
            subject: { // subject look a like
              next( val ) {
                  currVal = val;
                  isNextCalled = true;
              },
              complete() {
                  isCompleteCalled = true;
             ...