summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAlan Pearce2017-07-01 11:49:18 +0200
committerAlan Pearce2017-07-01 11:49:18 +0200
commitfb7e421b9efea0a96adcf30d30cc2d318980d928 (patch)
tree37595b22cfab571d93dcae1d848c404b93e86a63
parent248c74916e22f397ff95944ac2596b9e40b302e5 (diff)
downloadhomestead-fb7e421b9efea0a96adcf30d30cc2d318980d928.tar.lz
homestead-fb7e421b9efea0a96adcf30d30cc2d318980d928.tar.zst
homestead-fb7e421b9efea0a96adcf30d30cc2d318980d928.zip
Switch templating to hyperfast
This also means that highland is not (currently) required
-rw-r--r--package.json3
-rw-r--r--src/actions.js59
-rw-r--r--src/responders.js116
-rw-r--r--src/templates/home.html12
-rw-r--r--src/templates/post.html20
-rw-r--r--test/app.test.js1
-rw-r--r--yarn.lock52
7 files changed, 108 insertions, 155 deletions
diff --git a/package.json b/package.json
index 1bab4eb..db17e2f 100644
--- a/package.json
+++ b/package.json
@@ -46,14 +46,13 @@
   "dependencies": {
     "configly": "^4.1.0",
     "gray-matter": "^2.1.1",
-    "highland": "^2.11.0",
+    "hyperfast": "^2.1.0",
     "indent-string": "^3.1.0",
     "koa": "^2.2.0",
     "koa-helmet": "^3.2.0",
     "koa-router": "^7.2.1",
     "koa-send": "^4.1.0",
     "markdown-it": "^8.3.1",
-    "rheo": "^2.2.0",
     "toml": "^2.3.2"
   }
 }
diff --git a/src/actions.js b/src/actions.js
index 02414a1..11acff5 100644
--- a/src/actions.js
+++ b/src/actions.js
@@ -1,46 +1,41 @@
-'use strict'
+"use strict";
 
-const send = require('koa-send')
-const h = require('highland')
-const responders = require('./responders')
+const send = require("koa-send");
+const responders = require("./responders");
 
-function toArrayStream (iterator) {
-  return h(iterator.entries())
+function home(config, posts) {
+  const postsArray = Array.from(posts.values());
+  return async function(ctx, next) {
+    responders.home(ctx, config, postsArray);
+  };
 }
 
-function home (config, posts) {
-  const postsStream = toArrayStream(posts)
-  return async function (ctx, next) {
-    responders.home(ctx, config, postsStream)
-  }
-}
-
-function post (config, posts) {
-  return async function (ctx, next) {
-    ctx.assert(posts.has(ctx.params.filename), 404, 'Post not found')
-    const post = posts.get(ctx.params.filename)
+function post(config, posts) {
+  return async function(ctx, next) {
+    ctx.assert(posts.has(ctx.params.filename), 404, "Post not found");
+    const post = posts.get(ctx.params.filename);
 
-    responders.post(ctx, config, post)
-  }
+    responders.post(ctx, config, post);
+  };
 }
 
-function taxonGenerator (config, term, items) {
-  return async function (ctx, next) {
-    const value = ctx.params.value
-    ctx.assert(items.has(ctx.params.value), 404, `${term} ${value} not found`)
+function taxonGenerator(config, term, items) {
+  return async function(ctx, next) {
+    const value = ctx.params.value;
+    ctx.assert(items.has(ctx.params.value), 404, `${term} ${value} not found`);
 
-    const taxonItems = toArrayStream(items.get(value))
+    const taxonItems = items.get(value);
 
-    responders.taxon(ctx, config, taxonItems)
-  }
+    responders.taxon(ctx, config, taxonItems);
+  };
 }
 
-const prefix = /^\/static\//
-async function serveFiles (ctx) {
+const prefix = /^\/static\//;
+async function serveFiles(ctx) {
   if (prefix.test(ctx.path)) {
-    await send(ctx, ctx.path.replace(prefix, ''), {
-      root: './static'
-    })
+    await send(ctx, ctx.path.replace(prefix, ""), {
+      root: "./static"
+    });
   }
 }
 
@@ -49,4 +44,4 @@ module.exports = {
   post,
   taxonGenerator,
   serveFiles
-}
+};
diff --git a/src/responders.js b/src/responders.js
index e472579..9633e15 100644
--- a/src/responders.js
+++ b/src/responders.js
@@ -1,13 +1,8 @@
 "use strict";
 
-const h = require("highland");
 const fs = require("fs");
-const rheo = require("rheo");
+const hyperfast = require("hyperfast");
 const indent = require("indent-string");
-const PassThrough = require("stream").PassThrough;
-
-const toLines = string =>
-  string.split("\n").map((s, i, arr) => (i === arr.length - 1 ? s : s + "\n"));
 
 const getTemplate = name =>
   fs.readFileSync(`${__dirname}/templates/${name}.html`, "utf8");
@@ -15,21 +10,15 @@ const getTemplate = name =>
 const findMain = /^(\s+)<main/m;
 const baseIndentLevel = findMain.exec(getTemplate("layout"))[1].length;
 const postIndentLevel =
-  baseIndentLevel + findMain.exec(getTemplate("post"))[1].length;
+  baseIndentLevel +
+  /^(\s+)<div class="post-content/m.exec(getTemplate("post"))[1].length;
 
 function indentForTemplate(text, indentLevel) {
   return indent(text, indentLevel).slice(indentLevel).replace(/\n+$/, "");
 }
 
 function templateReader(template, indentLevel) {
-  const content = toLines(
-    indentForTemplate(getTemplate(template), indentLevel)
-  );
-  return () => h(content);
-}
-
-function prependDoctype(stream) {
-  return h(["<!DOCTYPE html>"]).concat(stream).pipe(new PassThrough());
+  return indentForTemplate(getTemplate(template), indentLevel);
 }
 
 const templates = {
@@ -39,29 +28,27 @@ const templates = {
   taxon: templateReader("taxon", baseIndentLevel)
 };
 
-function setTitle(siteTitle, pageTitle) {
-  return rheo.template(function(s) {
-    return s
-      .inner(
-        "title",
-        rheo(pageTitle ? `${pageTitle} · ${siteTitle}` : siteTitle)
-      )
-      .inner("body header h1", rheo(siteTitle));
-  });
-}
-
-function renderPostListItem(ctx) {
-  return function(template, [, post]) {
-    return template
-      .attribute("a", "href", () => ctx.getURL("post", post.basename))
-      .inner("a", () => rheo(post.data.get("title")));
-  };
+function title(siteTitle, pageTitle) {
+  return pageTitle ? `${pageTitle} · ${siteTitle}` : siteTitle;
 }
 
-function showPage(name) {
-  return function(els) {
-    return rheo(templates[name]());
-  };
+const renderPostListItem = ctx => post => ({
+  a: {
+    href: ctx.getURL(post, post.basename),
+    _text: post.data.get("title")
+  }
+});
+
+function layout(config, pageTitle, pageElement) {
+  return hyperfast(templates.layout, {
+    title: title(config.site.author.name, pageTitle),
+    "body > header .p-name": config.site.author.name,
+    "body > header .u-photo": {
+      alt: config.site.author.name,
+      src: config.site.author.photo
+    },
+    "body > main": pageElement
+  }).outerHTML.trim();
 }
 
 module.exports = {
@@ -69,51 +56,42 @@ module.exports = {
   postIndentLevel,
   indentForTemplate,
 
-  home(ctx, config, postsStream) {
+  home(ctx, config, posts) {
     ctx.type = "html";
 
-    ctx.body = prependDoctype(
-      templates
-        .layout()
-        .pipe(rheo())
-        .attribute(".u-photo", "alt", config.site.author.name)
-        .attribute(".u-photo", "src", config.site.author.photo)
-        .outer("main", showPage("home"))
-        .inner(".posts", function(postsTemplate) {
-          return postsStream.pipe(postsTemplate.map(renderPostListItem(ctx)));
-        })
-        .pipe(setTitle(config.site.author.name))
-        .render()
+    ctx.body = layout(
+      config,
+      null,
+      hyperfast(templates.home, {
+        ".post": posts.map(renderPostListItem(ctx))
+      })
     );
   },
 
   post(ctx, config, post) {
     ctx.type = "html";
-    ctx.body = prependDoctype(
-      templates
-        .layout()
-        .pipe(rheo())
-        .outer("main", showPage("post"))
-        .inner("article h1", rheo(post.data.get("title")))
-        .outer("article main", rheo(post.body))
-        .pipe(setTitle(config.site.author.name, post.data.get("title")))
-        .render()
+
+    ctx.body = layout(
+      config,
+      post.data.get("title"),
+      hyperfast(templates.post, {
+        "article h1": post.data.get("title"),
+        "article .post-content": {
+          _html: post.body
+        }
+      })
     );
   },
 
   taxon(ctx, config, taxonItems) {
     ctx.type = "html";
-    ctx.body = prependDoctype(
-      templates
-        .layout()
-        .pipe(rheo())
-        .outer("main", showPage("taxon"))
-        .inner("h1", rheo(config.site.author.name))
-        .inner(".posts", function(postsTemplate) {
-          return taxonItems.pipe(postsTemplate.map(renderPostListItem(ctx)));
-        })
-        .pipe(setTitle(config.site.author.name))
-        .render()
+
+    ctx.body = layout(
+      config,
+      null,
+      hyperfast(templates.taxon, {
+        ".post": taxonItems.map(renderPostListItem(ctx))
+      })
     );
   }
 };
diff --git a/src/templates/home.html b/src/templates/home.html
index dfc4677..97ac89a 100644
--- a/src/templates/home.html
+++ b/src/templates/home.html
@@ -1,7 +1,5 @@
-<main class="home">
-  <ul class="posts">
-    <li class="post">
-      <a href="/">Test post please ignore</a>
-    </li>
-  </ul>
-</main>
+<ul class="posts">
+  <li class="post">
+    <a href="/">Test post please ignore</a>
+  </li>
+</ul>
diff --git a/src/templates/post.html b/src/templates/post.html
index b6eba4e..384e6bb 100644
--- a/src/templates/post.html
+++ b/src/templates/post.html
@@ -1,11 +1,9 @@
-<main class="post">
-  <article>
-    <h1>post title</h1>
-    <main>
-      Fringilla ut morbi tincidunt augue interdum velit euismod!
-      Interdum velit laoreet id donec ultrices tincidunt arcu, non
-      sodales neque sodales ut etiam sit amet nisl purus, in
-      mollis nunc sed.
-    </main>
-  </article>
-</main>
+<article>
+  <h1>post title</h1>
+  <div class="post-content">
+    Fringilla ut morbi tincidunt augue interdum velit euismod!
+    Interdum velit laoreet id donec ultrices tincidunt arcu, non
+    sodales neque sodales ut etiam sit amet nisl purus, in
+    mollis nunc sed.
+  </div>
+</article>
diff --git a/test/app.test.js b/test/app.test.js
index f3d8f07..3cffaf5 100644
--- a/test/app.test.js
+++ b/test/app.test.js
@@ -32,6 +32,7 @@ test("homepage", t => {
       t.is($("head > title").text(), "John Doe");
       t.is($("h1").text(), "John Doe");
       t.is($("main").length, 1);
+      t.is($("main .posts").length, 1);
       return $;
     })
     .then(toMicroformatsOptions)
diff --git a/yarn.lock b/yarn.lock
index a1f5a83..d623708 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1153,7 +1153,7 @@ crypto-random-string@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
 
-css-select@~1.2.0:
+css-select@^1.1.0, css-select@~1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
   dependencies:
@@ -1166,12 +1166,6 @@ css-what@2.1:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
 
-cssauron@^1.2.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/cssauron/-/cssauron-1.4.0.tgz#a6602dff7e04a8306dc0db9a551e92e8b5662ad8"
-  dependencies:
-    through X.X.X
-
 currently-unhandled@^0.4.1:
   version "0.4.1"
   resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
@@ -1399,7 +1393,7 @@ domutils@1.5.1:
     dom-serializer "0"
     domelementtype "1"
 
-domutils@^1.5.1:
+domutils@^1.5.0, domutils@^1.5.1:
   version "1.6.2"
   resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.6.2.tgz#1958cc0b4c9426e9ed367fb1c8e854891b0fa3ff"
   dependencies:
@@ -1416,10 +1410,6 @@ dot-prop@^4.1.0:
   dependencies:
     is-obj "^1.0.0"
 
-double-ended-queue@^0.9.7:
-  version "0.9.7"
-  resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-0.9.7.tgz#8ae0a7265df66cdc3f07dce558e9716adb586ab8"
-
 duplexer2@^0.1.4:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
@@ -1467,6 +1457,10 @@ enhance-visitors@^1.0.0:
   dependencies:
     lodash "^4.13.1"
 
+ent@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
+
 entities@^1.1.1, entities@~1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
@@ -2359,12 +2353,6 @@ hide-powered-by@1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/hide-powered-by/-/hide-powered-by-1.0.0.tgz#4a85ad65881f62857fc70af7174a1184dccce32b"
 
-highland@^2.11.0:
-  version "2.11.0"
-  resolved "https://registry.yarnpkg.com/highland/-/highland-2.11.0.tgz#4d156709c5f10bc31cab6a97c7feb6c373e2466d"
-  dependencies:
-    util-deprecate "^1.0.2"
-
 hoek@2.x.x:
   version "2.16.3"
   resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
@@ -2390,7 +2378,7 @@ hsts@2.0.0:
   dependencies:
     core-util-is "1.0.2"
 
-htmlparser2@^3.8.3, htmlparser2@^3.9.1:
+htmlparser2@^3.8.2, htmlparser2@^3.9.1:
   version "3.9.2"
   resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
   dependencies:
@@ -2461,6 +2449,15 @@ husky@^0.13.4:
     is-ci "^1.0.9"
     normalize-path "^1.0.0"
 
+hyperfast@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/hyperfast/-/hyperfast-2.1.0.tgz#72c91f87126c54e6fe0ad2264ece278b3a6c0a56"
+  dependencies:
+    css-select "^1.1.0"
+    domutils "^1.5.0"
+    ent "^2.2.0"
+    htmlparser2 "^3.8.2"
+
 iconv-lite@^0.4.17:
   version "0.4.18"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2"
@@ -4445,15 +4442,6 @@ restore-cursor@^2.0.0:
     onetime "^2.0.0"
     signal-exit "^3.0.2"
 
-rheo@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/rheo/-/rheo-2.2.0.tgz#614187095b12847f49f284e2f804ad59623ca243"
-  dependencies:
-    cssauron "^1.2.0"
-    double-ended-queue "^0.9.7"
-    htmlparser2 "^3.8.3"
-    void-elements "^2.0.1"
-
 rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1:
   version "2.6.1"
   resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
@@ -4854,7 +4842,7 @@ through2@^2.0.0:
     readable-stream "^2.1.5"
     xtend "~4.0.1"
 
-through@X.X.X, through@^2.3.6:
+through@^2.3.6:
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
 
@@ -5005,7 +4993,7 @@ user-home@^2.0.0:
   dependencies:
     os-homedir "^1.0.0"
 
-util-deprecate@^1.0.2, util-deprecate@~1.0.1:
+util-deprecate@~1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
 
@@ -5034,10 +5022,6 @@ verror@1.3.6:
   dependencies:
     extsprintf "1.0.2"
 
-void-elements@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
-
 which-module@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"