<h2 id="header"></h2>

<label for="someinput">Title: </label>
<input id="someinput" type="text">
// Based on mithril-stream
// https://github.com/MithrilJS/mithril.js/blob/next/stream/stream.js

function Stream(state) {
  let listeners = [];

  let stream = function(value) {
    if(arguments.length > 0) {
      state = value;
      listeners.forEach(fn => fn(value));
    }

    return state;
  }

  stream.map = function(fn) {
    // Create new instance with transformed state.
    // This will execute the callback when calling `map`
    // this might not be what you want if you use a 
    // function that has side effects. Just beware.
    let target = Stream(fn(state));

    // Transform the value and update stream
    const listener = value => target(fn(value));

    // Update the source listeners
    listeners.push(listener);

    return target;
  }

  return stream;
}

function slug_str(value) {
  return value.toLowerCase().replace(/\W/g, "-")
}

function update_header(text) {
  header.textContent = text;
}

const title = Stream('Initial title');
const slug = title.map(slug_str);

// `update_header` returns undefined
// so the new stream is useless
slug.map(update_header);

// Input initial state
someinput.value = title();

// Bind the input to header
someinput.addEventListener('keyup', e => title(e.target.value))

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.