Arrow function problems

function foo(ddb) {
  return {
    listTables: (params = {}, cb = idFunc) => {
      const self = this
      let currentList = params.currentList || []
      
      return toPromise(ddb, ddb.listTables, omit(params, 'currentList'), cb)
        .then(r => {
          console.log('LISTTABLES result', r)
          currentList = currentList.concat(r.TableNames || [])
          
          if (!r.LastEvaluatedTableName || r.TableNames.length === 0) {
            return { ...r, TableNames: currentList }
          }

          return self.listTables({   // <- Fails here
              ...params,
              currentList,
              ExclusiveStartTableName: r.LastEvaluatedTableName,
            }, cb)
        })
    }
  }
}
class MyClass {
  myMethod = () => {
    // ...code
  }
}

Brookjs components strawman proposal

import { h, component } from 'brookjs'
import { editClick } from '../actions'

// Changes only occur when bound to a stream
export default component({
    render: props$ => (
        <li>
            {/* Text changes when a value is emitted. */}
            <p class="todo__name">
                {props$.map(props => props.text)}
            </p>
            {/* Maps a stream of events to actions. */}
            <button onClick={event$ => event$.map(editClick)}>
                {'Edit todo'}
            </button>
        </li>
    )
})
import { h, component } from 'brookjs'
import TodoItem from './TodoItem'

export default component({
    render: props$ => (
        <div>
            <h2>My Todos</h2>
            {/**
              * `order` provides sequence todos should appear
              * `dict` provides a performant instance lookup 
              */}
            <ul>
                {props$.map(todos => todos.order.map(key => (
                    <TodoItem
                        props$={props$.map(todos => todos.dict[key])}
                        key={key}
                        preplug={instance$ => instance$.map(action => ({
                            ...action,
                            meta: { key }
                        })} />
                )))}
            <ul>
        </div>
    )
})
import { h, component } from 'brookjs'
import TodoList from './TodoList'

export default component({
    render: props$ => (
        <div>
            <h1>Todo App</h1>
            {/**
              * Individual attributes respond to observables
              * Performance optimized inline
              */}
            <input value={props$.map(props => props.editing).skipDuplicates()}
                   onInput={event$ => event$.map(event => editTodo(event.target.value))} />
            <button onClick={event$ => event$.map(addTodo)}>Add Todo</button>
            <TodoList props$={props$.map(props => props.todos)} />
        </div>
    )
})
import { createStore, applyMiddleware } from 'redux'
import { h, observeDelta, Kefir } from brookjs
import { App } from './components'
import { selectProps } from './selectors'

const store = createStore(
    (state, action) => state, // reducer
    window.__INITIAL_STATE__ || {},
    applyMiddleware(observeDelta(
        /* register deltas here */
    )
)
const state$ = Kefir.fromESObservable(store)

/**
 * `mount` thus takes the DOM to mount
 * and the element to bind it to, and
 * returns a stream. Note that because
 * of how streams work, nothing happens
 * until the stream is observed.
 */
const view$ = mount(
    <App props$={selectProps(state$)} />,
    document.getElementById('app')
)
 
view$.observe(store.dispatch)
import { h, component, list } from 'brookjs'
import TodoItem from './TodoItem'

export default component({
    render: props$ => (
        <div>
            <h2>My Todos</h2>
            <ul>
                {/* Must be a stream of objects with `order` & `dict` */}
                {list(props$, (props$, key) => (
                    <TodoItem
                        props$={props$}
                        key={key}
                        preplug={instance$ => instance$.map(action => ({
                            ...action,
                            meta: { key }
                        })} />
                )}
            <ul>
        </div>
    )
})
import { createStore, applyMiddleware } from 'redux'
import { h, observeDelta, Kefir } from brookjs
import { App } from './components'
import { selectProps } from './selectors'

const el = document.getElementById('app')

const store = createStore(
    (state, action) => state,
    window.__INITIAL_STATE__ || {},
    applyMiddleware(observeDelta(
        /* register deltas here */
        domDelta({ el, selectProps, view: App })
    )
)

// Everything is bound to the store immediately,
// but an init action makes sure everything waits
// until the store is fully instantiated.
store.dispatch(init())

Point-Free Style – Functional Light JS v2 from Front-End Masters

function output(txt) {
	console.log(txt);
}

function printIf(predicate) {
	return function(msg) {
		if (predicate(msg)) {
			output(msg);
		}
	};
}

function isShortEnough(str) {
	return str.length <= 5;
}

function isLongEnough(str) {
	return !isShortEnough(str);
}

var msg1 = "Hello";
var msg2 = msg1 + " World";

printIf(isShortEnough)(msg1);		// Hello
printIf(isShortEnough)(msg2);
printIf(isLongEnough)(msg1);
printIf(isLongEnough)(msg2);		// Hello World
const output = console.log.bind(console);
const when = func => pred => val => {
  if (predicate(val)) {
    func(val);
  }
};
const not = func => val => !func(val);
const printIf = when(output);
const isShortEnough = str => str.length <= 5;
const isLongEnough = not(isShortEnough);

Simple Path

const getPath = (path, target) =>
    path.split('.')
        .reduce((value, key) => value[key], target);

// Usage
const path = 'a.b.c';
const target = {
    a: {
        b: {
            c: true
        }
    }
};

assert(true === getPath(path, target));

Removed brookjs Actions

/**
 * Value change Action type.
 *
 * @type {string}
 */
export const VALUE_CHANGE = 'VALUE_CHANGE';

/**
 * Create a new Value Change action.
 *
 * @param {string} value - Target value.
 * @returns {Action} Value Change action object.
 */
export function valueEventAction(value) {
    return {
        type: VALUE_CHANGE,
        payload: { value }
    };
}

/**
 * Field focus event action type.
 *
 * @type {string}
 */
export const FIELD_FOCUS = 'FIELD_FOCUS';

/**
 * Create a FIELD_FOCUS action object.
 *
 * @param {string} name - Field name.
 * @returns {Action} FIELD_FOCUS action.
 */
export function fieldFocusAction(name) {
    return {
        type: FIELD_FOCUS,
        payload: { name }
    };
}

/**
 * Checked change constant.
 *
 * @type {string}
 */
export const CHECKED_CHANGE = 'CHECKED_CHANGE';

/**
 * Create a new Checked Change action.
 *
 * @param {boolean} value - Target checked.
 * @returns {Action} Checked Change action object.
 */
export function checkedEventAction(value) {
    return {
        type: CHECKED_CHANGE,
        payload: { value }
    };
}

/**
 * Click event Action type.
 *
 * @type {string}
 */
export const CLICK = 'CLICK';

/**
 * Create a new Clicked Action
 *
 * @returns {Action} Clicked action object.
 */
export function clickedEventAction() {
    return { type: CLICK };
}

Observable Rendering

import Kefir from 'kefir';

export default function EditorComponent(el, props$) {
    const keyup$ = Kefir.fromEvents(el, 'keyup');
    const keydown$ = Kefir.fromEvents(el, 'keydown');

    return props$.sampledBy(keyup$.debounce(150))
        .flatMapLatest(props =>
            createRenderStream(props).takeUntil(keydown$)
        );

    function createRenderStream(props) {
        return Kefir.stream(emitter => {
            const loop = requestAnimationFrame(() => {
                // Update the element
                emitter.end();
            });

            return () => cancelAnimationFrame(loop);
        });
    }
};

IDs & Classes: Problem

<!DOCTYPE html>
<html>
<head>
    <title>Movies and Shows</title>
</head>
<body>
<h1>Amazing Movies and TV Shows Ever!</h1>
<ol>
    <li>Finding Dory</li>
    <li>Game of Thrones</li>
    <li>Star Wars: The Force Awakens</li>
    <li>Life of Pi</li>
    <li>Dancing with the Stars</li>
    <li>The Walking Dead</li>
</ol>
</body>
</html>

Developer /etc/hosts

192.30.253.113  github.com
151.101.44.133  assets-cdn.github.com
54.236.140.90   collector.githubapp.com
192.30.253.116  api.github.com
192.30.253.122  ssh.github.com
151.101.44.133  avatars0.githubusercontent.com
151.101.44.133  avatars1.githubusercontent.com
151.101.44.133  avatars2.githubusercontent.com
151.101.44.133  avatars3.githubusercontent.com
151.101.92.162 registry.npmjs.com
52.27.70.152   npmjs.com
104.244.42.65  twitter.com
151.101.65.69  stackoverflow.com