# cyclejs-fundamentals

Plunker example for cycleJS
SystemJS.config({
  map: {
    'app': './src',
    'xstream': 'https://unpkg.com/xstream@10.9.0/',
    'symbol-observable': 'https://unpkg.com/symbol-observable@1.0.4/lib/index.js',
    'Cycle': 'https://unpkg.com/@cycle/run@3.1.0/lib/index.js',
  },
  packages:{
    app:{
      main: 'main'
    },
    xstream:{
      main: 'dist/xstream.js'
    },
    run:{
      main: 'dist/cycle-run.js'
    }
  },
});
<!DOCTYPE html>
<html>

  <head>
    <script src="https://unpkg.com/systemjs/dist/system.js"></script>
    <script src="typescript-config.js"></script>
    <script src="app-config.js"></script>
    
  </head>

  <body>
    <div id="app"></div>
    
    <script>
      System.import('app')
        .catch(console.error.bind(console));
    </script>
  </body>

</html>
import xs from 'xstream'
import fromEvent from 'xstream/extra/fromEvent'
import { run } from 'Cycle'

function h(tagName, children) {
    return {
        tagName: tagName,
        children: children,
    };
}

function h1(children) {
    return {
        tagName: 'H1',
        children: children,
    }
}

function span(children) {
    return {
        tagName: 'SPAN',
        children: children,
    }
}

function main(sources) {
    const mouseover$ = sources.DOM.selectEvents('span', 'mouseover');
    return {
        DOM: mouseover$.startWith(null).map(() => 
            xs.periodic(1000)                       
             .fold(prev => prev + 1, 0)
          ).flatten()
             .map(i => 
               h1([
                 span([
                    `Seconds elapsed: ${i}`
                ])
              ])
            ),
            
         log: xs.periodic(2000)                       
           .fold(prev => prev + 1, 0)
    } 
}

// source = input (read) effect
// sink = output (write) effect

function domDriver(obj$) {
    function createElement(obj) {
        const element = document.createElement(obj.tagName);
        obj.children.forEach(child => {
            if (typeof child === 'object') {
                element.appendChild(createElement(child));
            } else {
              element.textContent = child;
            }
        })
        return element
    }
    
    
   obj$.subscribe({ next: obj => {
        const container = document.querySelector('#app');
        container.textContent = '';
        const element = createElement(obj);
        container.appendChild(element)
     }});  
     const domSource = {
         selectEvents: function (tagName, eventType) {
             return fromEvent(document, eventType)
                .filter(ev => ev.target.tagName === tagName.toUpperCase());
         }
     }
     return domSource;
}

function logDriver(msg$) {
    msg$.subscribe({ next: msg => { console.log(msg); }})
}

// Cycle.run
run(main, {
    DOM: domDriver,
    log: logDriver,
});



SystemJS.config({
  packages: {
    "ts": {
      "main": "lib/plugin.js"
    },
    "typescript": {
      "main": "lib/typescript.js",
      "meta": {
        "lib/typescript.js": {
          "exports": "ts"
        }
      }
    }
  },
  map: {
    "ts": "https://unpkg.com/plugin-typescript@7.1.0/",
    "typescript": "https://unpkg.com/typescript@2.4.2/"
  },
  transpiler: 'ts'
});