From 9208c43d11ff38c1ee3f6fc9639defd36715e8dd Mon Sep 17 00:00:00 2001 From: Vladimir Kutepov Date: Sun, 11 Feb 2018 21:15:36 +0700 Subject: [PATCH] Add Hyperapp --- benchmarks.js | 3 +- benchmarks/color-picker/hyperapp/.babelrc | 8 + benchmarks/color-picker/hyperapp/client.jsx | 29 ++ .../color-picker/hyperapp/components/App.jsx | 54 ++ benchmarks/color-picker/hyperapp/page.marko | 23 + .../color-picker/hyperapp/rollup.config.js | 25 + benchmarks/color-picker/hyperapp/server.jsx | 10 + .../hyperapp/util/serverRender.jsx | 6 + benchmarks/search-results/hyperapp/.babelrc | 8 + benchmarks/search-results/hyperapp/client.jsx | 30 ++ .../hyperapp/components/App.jsx | 50 ++ .../hyperapp/components/Footer.jsx | 483 ++++++++++++++++++ .../hyperapp/components/SearchResultsItem.jsx | 31 ++ benchmarks/search-results/hyperapp/page.marko | 23 + .../search-results/hyperapp/rollup.config.js | 22 + benchmarks/search-results/hyperapp/server.jsx | 12 + .../hyperapp/util/serverRender.jsx | 6 + package.json | 3 + 18 files changed, 825 insertions(+), 1 deletion(-) create mode 100644 benchmarks/color-picker/hyperapp/.babelrc create mode 100644 benchmarks/color-picker/hyperapp/client.jsx create mode 100644 benchmarks/color-picker/hyperapp/components/App.jsx create mode 100644 benchmarks/color-picker/hyperapp/page.marko create mode 100644 benchmarks/color-picker/hyperapp/rollup.config.js create mode 100644 benchmarks/color-picker/hyperapp/server.jsx create mode 100644 benchmarks/color-picker/hyperapp/util/serverRender.jsx create mode 100644 benchmarks/search-results/hyperapp/.babelrc create mode 100644 benchmarks/search-results/hyperapp/client.jsx create mode 100644 benchmarks/search-results/hyperapp/components/App.jsx create mode 100644 benchmarks/search-results/hyperapp/components/Footer.jsx create mode 100644 benchmarks/search-results/hyperapp/components/SearchResultsItem.jsx create mode 100644 benchmarks/search-results/hyperapp/page.marko create mode 100644 benchmarks/search-results/hyperapp/rollup.config.js create mode 100644 benchmarks/search-results/hyperapp/server.jsx create mode 100644 benchmarks/search-results/hyperapp/util/serverRender.jsx diff --git a/benchmarks.js b/benchmarks.js index 84c5e87..a3a5b88 100644 --- a/benchmarks.js +++ b/benchmarks.js @@ -13,6 +13,7 @@ var enabledBenchmarks = null; enabledLibs = { marko: true, preact: true, + hyperapp: true, react: true, vue: true, inferno: true @@ -75,4 +76,4 @@ Object.keys(enabledBenchmarks).forEach((benchmarkName) => { }); }); -module.exports = benchmarks; \ No newline at end of file +module.exports = benchmarks; diff --git a/benchmarks/color-picker/hyperapp/.babelrc b/benchmarks/color-picker/hyperapp/.babelrc new file mode 100644 index 0000000..607530b --- /dev/null +++ b/benchmarks/color-picker/hyperapp/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": [ + ["es2015", { "loose": true, "modules": false }] + ], + "plugins": [ + ["transform-react-jsx", { "pragma": "h" }] + ] +} diff --git a/benchmarks/color-picker/hyperapp/client.jsx b/benchmarks/color-picker/hyperapp/client.jsx new file mode 100644 index 0000000..1418c00 --- /dev/null +++ b/benchmarks/color-picker/hyperapp/client.jsx @@ -0,0 +1,29 @@ +const { app } = require('hyperapp'); +const { state, actions, view } = require('./components/App'); + +const mountNode = document.getElementById('mount'); + +if (mountNode) { + const initialState = Object.assign({}, state, { colors: window.colors }); + app(initialState, actions, view, mountNode); + console.log('Re-rendering on client completed'); +} + +window.addBench('hyperapp', (el, colors) => { + const initialState = Object.assign({}, state, { colors }); + + let currentDone; + const appActions = Object.assign({}, actions, { + onUpdate() { + currentDone(); + } + }); + + const widget = app(initialState, appActions, view, el); + + let selectedColorIndex = 0; + return (done) => { + widget.setColorIndex((++selectedColorIndex) % colors.length); + currentDone = done; + }; +}); diff --git a/benchmarks/color-picker/hyperapp/components/App.jsx b/benchmarks/color-picker/hyperapp/components/App.jsx new file mode 100644 index 0000000..b4c54d4 --- /dev/null +++ b/benchmarks/color-picker/hyperapp/components/App.jsx @@ -0,0 +1,54 @@ +const { h } = require('hyperapp'); + +const state = { + selectedColorIndex: 0, + colors: [], +}; + +const actions = { + setColorIndex(selectedColorIndex) { + return { selectedColorIndex }; + }, + onUpdate() { + // for benchmark + }, +}; + +function renderColors(state, actions) { + if (state.colors.length) { + return ( + + ); + } else { + return
No colors!
+ } +} + +function view(state, actions) { + const currentColor = state.colors[state.selectedColorIndex]; + return ( +
+

Choose your favorite color:

+
+ {renderColors(state, actions)} +
+
You chose:
{currentColor.name}
+
+ ); +} + +module.exports = { + state, + actions, + view, +}; diff --git a/benchmarks/color-picker/hyperapp/page.marko b/benchmarks/color-picker/hyperapp/page.marko new file mode 100644 index 0000000..2380339 --- /dev/null +++ b/benchmarks/color-picker/hyperapp/page.marko @@ -0,0 +1,23 @@ +import serverRender from './util/serverRender'; +import App from './components/App'; + + + <@body> + $ var renderedHTML = serverRender(App, input.colors); +
$!{renderedHTML}
+ + + + diff --git a/benchmarks/color-picker/hyperapp/rollup.config.js b/benchmarks/color-picker/hyperapp/rollup.config.js new file mode 100644 index 0000000..0b8c8d0 --- /dev/null +++ b/benchmarks/color-picker/hyperapp/rollup.config.js @@ -0,0 +1,25 @@ +import commonjsPlugin from 'rollup-plugin-commonjs'; +import browserifyPlugin from 'rollup-plugin-browserify-transform'; +import nodeResolvePlugin from 'rollup-plugin-node-resolve'; +import babelPlugin from 'rollup-plugin-babel'; +import envify from 'envify'; +import path from 'path'; + +process.env.NODE_ENV = 'production'; + +export default { + input: path.resolve(__dirname, 'client.jsx'), + output: { + format: 'iife', + file: path.join(process.env.BUNDLES_DIR, 'hyperapp.js') + }, + mame: 'app', + plugins: [ + babelPlugin({ + exclude: 'node_modules/**' + }), + browserifyPlugin(envify), + nodeResolvePlugin(), + commonjsPlugin() + ], +}; diff --git a/benchmarks/color-picker/hyperapp/server.jsx b/benchmarks/color-picker/hyperapp/server.jsx new file mode 100644 index 0000000..c906a79 --- /dev/null +++ b/benchmarks/color-picker/hyperapp/server.jsx @@ -0,0 +1,10 @@ +const { app } = require('hyperapp'); +const { renderToString } = require('hyperapp-render'); +const { state, actions, view } = require('./components/App'); + +module.exports = function(colors) { + return function benchFn() { + const initialState = Object.assign({}, state, { colors }); + return renderToString(view(initialState, actions)); + }; +}; diff --git a/benchmarks/color-picker/hyperapp/util/serverRender.jsx b/benchmarks/color-picker/hyperapp/util/serverRender.jsx new file mode 100644 index 0000000..5bd9d9b --- /dev/null +++ b/benchmarks/color-picker/hyperapp/util/serverRender.jsx @@ -0,0 +1,6 @@ +const { renderToString } = require('hyperapp-render'); + +module.exports = function infernoRender(App, colors) { + const state = Object.assign({}, App.state, { colors }); + return renderToString(App.view(state, App.actions)); +}; diff --git a/benchmarks/search-results/hyperapp/.babelrc b/benchmarks/search-results/hyperapp/.babelrc new file mode 100644 index 0000000..607530b --- /dev/null +++ b/benchmarks/search-results/hyperapp/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": [ + ["es2015", { "loose": true, "modules": false }] + ], + "plugins": [ + ["transform-react-jsx", { "pragma": "h" }] + ] +} diff --git a/benchmarks/search-results/hyperapp/client.jsx b/benchmarks/search-results/hyperapp/client.jsx new file mode 100644 index 0000000..c2d5b68 --- /dev/null +++ b/benchmarks/search-results/hyperapp/client.jsx @@ -0,0 +1,30 @@ +const { app } = require('hyperapp'); +const { state, actions, view } = require('./components/App'); + +const mountNode = document.getElementById('searchResultsMount'); + +if (mountNode) { + const initialState = Object.assign({}, state, { colors: window.searchResultsData }); + app(initialState, actions, view, mountNode); + console.log('Re-rendering on client completed'); +} + +window.addBench('hyperapp', (el, getNextSearchResults) => { + const initialState = Object.assign({}, state, { + getNextSearchResults: getNextSearchResults(), + }); + + let currentDone; + const appActions = Object.assign({}, actions, { + onUpdate() { + currentDone(); + } + }); + + const widget = app(initialState, appActions, view, el); + + return (done) => { + widget.setSearchResults(getNextSearchResults()); + currentDone = done; + }; +}); diff --git a/benchmarks/search-results/hyperapp/components/App.jsx b/benchmarks/search-results/hyperapp/components/App.jsx new file mode 100644 index 0000000..8555be9 --- /dev/null +++ b/benchmarks/search-results/hyperapp/components/App.jsx @@ -0,0 +1,50 @@ +const { h } = require('hyperapp'); +const Footer = require('./Footer'); +const SearchResultsItem = require('./SearchResultsItem'); + +const state = { + searchResultsData: { + items: [], + }, + purchased: { + // id-1: true, + // id-2: false + }, +}; + +const actions = { + setSearchResults(searchResultsData) { + return { searchResultsData }; + }, + onUpdate() { + // for benchmark + }, + purchased: { + buy(id) { + return { [id]: true }; + } + } +}; + +function view(state, actions) { + return ( +
+
+ {state.searchResultsData.items.map((item) => ( + + ))} +
+
+
+ ); +} + +module.exports = { + state, + actions, + view, +}; diff --git a/benchmarks/search-results/hyperapp/components/Footer.jsx b/benchmarks/search-results/hyperapp/components/Footer.jsx new file mode 100644 index 0000000..20b44f0 --- /dev/null +++ b/benchmarks/search-results/hyperapp/components/Footer.jsx @@ -0,0 +1,483 @@ +const { h } = require('hyperapp'); + +function Footer() { + return ( + + ); +} + +module.exports = Footer; diff --git a/benchmarks/search-results/hyperapp/components/SearchResultsItem.jsx b/benchmarks/search-results/hyperapp/components/SearchResultsItem.jsx new file mode 100644 index 0000000..56a5138 --- /dev/null +++ b/benchmarks/search-results/hyperapp/components/SearchResultsItem.jsx @@ -0,0 +1,31 @@ +const { h } = require('hyperapp'); + +function SearchResultsItem(props) { + const { item, purchased, buy } = props; + return ( +
+

{item.title}

+
+
+ + {item.title}/ + +
+
+ {item.price} + {purchased ? ( +
Purchased!
+ ) : ( + + )} +
+ ); +} + +module.exports = SearchResultsItem; diff --git a/benchmarks/search-results/hyperapp/page.marko b/benchmarks/search-results/hyperapp/page.marko new file mode 100644 index 0000000..e78fe00 --- /dev/null +++ b/benchmarks/search-results/hyperapp/page.marko @@ -0,0 +1,23 @@ +import serverRender from './util/serverRender'; +import App from './components/App'; + + + <@body> + $ var renderedHTML = serverRender(App, input.searchResults); +
$!{renderedHTML}
+ + + + diff --git a/benchmarks/search-results/hyperapp/rollup.config.js b/benchmarks/search-results/hyperapp/rollup.config.js new file mode 100644 index 0000000..74d7082 --- /dev/null +++ b/benchmarks/search-results/hyperapp/rollup.config.js @@ -0,0 +1,22 @@ +import commonjsPlugin from 'rollup-plugin-commonjs'; +import nodeResolvePlugin from 'rollup-plugin-node-resolve'; +import babelPlugin from 'rollup-plugin-babel'; +import path from 'path'; + +process.env.NODE_ENV = 'production'; + +export default { + input: path.resolve(__dirname, 'client.jsx'), + output: { + format: 'iife', + file: path.join(process.env.BUNDLES_DIR, 'hyperapp.js') + }, + mame: 'app', + plugins: [ + babelPlugin({ + exclude: 'node_modules/**' + }), + nodeResolvePlugin(), + commonjsPlugin() + ], +}; diff --git a/benchmarks/search-results/hyperapp/server.jsx b/benchmarks/search-results/hyperapp/server.jsx new file mode 100644 index 0000000..ebc9806 --- /dev/null +++ b/benchmarks/search-results/hyperapp/server.jsx @@ -0,0 +1,12 @@ +const { app } = require('hyperapp'); +const { renderToString } = require('hyperapp-render'); +const { state, actions, view } = require('./components/App'); + +module.exports = function(getNextSearchResults) { + return function benchFn() { + const initialState = Object.assign({}, state, { + getNextSearchResults: getNextSearchResults(), + }); + return renderToString(view(initialState, actions)) + }; +}; diff --git a/benchmarks/search-results/hyperapp/util/serverRender.jsx b/benchmarks/search-results/hyperapp/util/serverRender.jsx new file mode 100644 index 0000000..5bd9d9b --- /dev/null +++ b/benchmarks/search-results/hyperapp/util/serverRender.jsx @@ -0,0 +1,6 @@ +const { renderToString } = require('hyperapp-render'); + +module.exports = function infernoRender(App, colors) { + const state = Object.assign({}, App.state, { colors }); + return renderToString(App.view(state, App.actions)); +}; diff --git a/package.json b/package.json index 2aced70..cc18f58 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "bundle-marko": "node ./scripts/rollup.js marko", "bundle-react": "node ./scripts/rollup.js react", "bundle-preact": "node ./scripts/rollup.js preact", + "bundle-hyperapp": "node ./scripts/rollup.js hyperapp", "bundle-vue": "npm run bundle-vue-server && node ./scripts/rollup.js vue", "bundle-vue-server": "webpack --config benchmarks/color-picker/vue/webpack.config.js && webpack --config benchmarks/search-results/vue/webpack.config.js" }, @@ -47,6 +48,8 @@ "express": "^4.11.2", "format-number": "^3.0.0", "google-closure-compiler-js": "^20170910.0.0", + "hyperapp": "^1.1.2", + "hyperapp-render": "^1.1.0", "inferno": "^3.9.0", "inferno-component": "^3.9.0", "inferno-server": "^3.9.0",