Handling events that bubble consists of creating an observable of the events on the top most element and filtering the stream, e.g.
let view,
    formView;
formView = (count, query) =>
    <form id='search-form'>
        <input type='text' id='query' />
        <div>count: {count}, query: {query}</div>
    </form>;
view = () => {
    let input,
        count = 0;
    input = Observable
        .fromEvent(document, 'keyup')
        .filter(e => e.target.id === 'query');
    return input
        .map((e) => {
            return formView(++count, e.target.value);
        })
        .startWith(formView(0));
}
I do not understand how to subscribe to an event that does not bubble, e.g. "focus"
input = Observable
        // event 'focus' does not bubble to the document
        .fromEvent(document, 'focus')
        .filter(e => e.target.id === 'query');
I cannot do:
input = Observable
    .fromEvent(document.querySelector('#query'), 'focus')
    [..]
because at the time the code is executed, #query element does not exist.