Skip to content

Instantly share code, notes, and snippets.

@theadam
Created January 18, 2017 16:56
Show Gist options
  • Save theadam/24f08eb067a8f8c1375ba290ec18d707 to your computer and use it in GitHub Desktop.
Save theadam/24f08eb067a8f8c1375ba290ec18d707 to your computer and use it in GitHub Desktop.
esnextbin sketch
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>ESNextbin Sketch</title>
<!-- put additional styles and scripts here -->
</head>
<body>
<div id="app"><div id="test"></div></div>
</body>
</html>
/** @jsx h */
import { createElement } from 'react';
import { render } from 'react-dom';
const upper = c => c && c === c.toUpperCase();
const mapObj = (obj, fn) => Object.keys(obj).reduce((acc, k) => ({ ...acc, [k]: fn(obj[k]) }), {});
const eventProp = v => v.startsWith('on') && upper(v[2]);
function h(tag, jsxProps, ...children) {
const props = jsxProps || {};
return dispatch => (state) => {
const resolve = sub => {
if (isSubscribe(sub)) return sub.run(state);
else if (isHandler(sub)) return sub.handle(dispatch);
else if (typeof sub === 'function') return sub(dispatch)(state);
return sub;
}
const c = children.map(resolve);
const p = mapObj(props, resolve);
return createElement(tag, p, c);
};
}
function startApp(init, reducer, view) {
const node = document.createElement('div');
document.body.appendChild(node);
let state = init;
function dispatch(e) {
state = reducer(state, e);
render(loadedView(state), node);
}
const loadedView = view(dispatch)
render(loadedView(state), node);
}
const handlerSym = Symbol('handler');
function Handler(mapper = id => id) {
return {
[handlerSym]: true,
handle: cb => (e) => {
cb(mapper(e));
},
map(fn) {
return Handler(v => fn(mapper(v)));
}
}
}
const target = Handler(e => e.target);
const value = target.map(t => t.value);
const always = v => Handler(e => v);
const subscribeSym = Symbol('subscribe');
function Subscribe(mapper = v => v) {
return {
[subscribeSym]: true,
map(fn) {
return Subscribe(v => fn(mapper(v)));
},
run(val) {
return mapper(val);
},
}
}
const isSubscribe = v => v[subscribeSym] === true;
const isHandler = v => v[handlerSym] === true;
////////////////////////////////
const init = { value: 0 };
// Actions
const Action = {
increment(amt) {
return { type: Action.increment, value: amt };
}
}
// Reducer
function reducer(state, action) {
if (action.type === Action.increment) {
return { ...state, value: state.value + 1 };
}
return state;
}
// Queries
const val = Subscribe(state => state.value)
// View
const view = (
<div>
<button onClick={always(Action.increment(1))}>Click to increment</button>
<div>{val}</div>
</div>
);
startApp(init, reducer, view);
{
"name": "esnextbin-sketch",
"version": "0.0.0",
"dependencies": {
"react": "15.4.2",
"react-dom": "15.4.2",
"babel-runtime": "6.20.0"
}
}
'use strict';
var _symbol = require('babel-runtime/core-js/symbol');
var _symbol2 = _interopRequireDefault(_symbol);
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _extends3 = require('babel-runtime/helpers/extends');
var _extends4 = _interopRequireDefault(_extends3);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _react = require('react');
var _reactDom = require('react-dom');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/** @jsx h */
var upper = function upper(c) {
return c && c === c.toUpperCase();
};
var mapObj = function mapObj(obj, fn) {
return (0, _keys2.default)(obj).reduce(function (acc, k) {
return (0, _extends4.default)({}, acc, (0, _defineProperty3.default)({}, k, fn(obj[k])));
}, {});
};
var eventProp = function eventProp(v) {
return v.startsWith('on') && upper(v[2]);
};
function h(tag, jsxProps) {
for (var _len = arguments.length, children = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
children[_key - 2] = arguments[_key];
}
var props = jsxProps || {};
return function (dispatch) {
return function (state) {
var resolve = function resolve(sub) {
if (isSubscribe(sub)) return sub.run(state);else if (isHandler(sub)) return sub.handle(dispatch);else if (typeof sub === 'function') return sub(dispatch)(state);
return sub;
};
var c = children.map(resolve);
var p = mapObj(props, resolve);
return (0, _react.createElement)(tag, p, c);
};
};
}
function startApp(init, reducer, view) {
var node = document.createElement('div');
document.body.appendChild(node);
var state = init;
function dispatch(e) {
state = reducer(state, e);
(0, _reactDom.render)(loadedView(state), node);
}
var loadedView = view(dispatch);
(0, _reactDom.render)(loadedView(state), node);
}
var handlerSym = (0, _symbol2.default)('handler');
function Handler() {
var _ref;
var mapper = arguments.length <= 0 || arguments[0] === undefined ? function (id) {
return id;
} : arguments[0];
return _ref = {}, (0, _defineProperty3.default)(_ref, handlerSym, true), (0, _defineProperty3.default)(_ref, 'handle', function handle(cb) {
return function (e) {
cb(mapper(e));
};
}), (0, _defineProperty3.default)(_ref, 'map', function map(fn) {
return Handler(function (v) {
return fn(mapper(v));
});
}), _ref;
}
var target = Handler(function (e) {
return e.target;
});
var value = target.map(function (t) {
return t.value;
});
var always = function always(v) {
return Handler(function (e) {
return v;
});
};
var subscribeSym = (0, _symbol2.default)('subscribe');
function Subscribe() {
var _ref2;
var mapper = arguments.length <= 0 || arguments[0] === undefined ? function (v) {
return v;
} : arguments[0];
return _ref2 = {}, (0, _defineProperty3.default)(_ref2, subscribeSym, true), (0, _defineProperty3.default)(_ref2, 'map', function map(fn) {
return Subscribe(function (v) {
return fn(mapper(v));
});
}), (0, _defineProperty3.default)(_ref2, 'run', function run(val) {
return mapper(val);
}), _ref2;
}
var isSubscribe = function isSubscribe(v) {
return v[subscribeSym] === true;
};
var isHandler = function isHandler(v) {
return v[handlerSym] === true;
};
////////////////////////////////
var init = { value: 0 };
// Actions
var Action = {
increment: function increment(amt) {
return { type: Action.increment, value: amt };
}
};
// Reducer
function reducer(state, action) {
if (action.type === Action.increment) {
return (0, _extends4.default)({}, state, { value: state.value + 1 });
}
return state;
}
// Queries
var val = Subscribe(function (state) {
return state.value;
});
// View
var view = h(
'div',
null,
h(
'button',
{ onClick: always(Action.increment(1)) },
'Click to increment'
),
h(
'div',
null,
val
)
);
startApp(init, reducer, view);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment