2274849cbe5a72e68647d038c0a7a8f883e3005e — Martin Angers 4 months ago 51cff7f
start converging towards a functional-friendly middleware signature
3 files changed, 30 insertions(+), 11 deletions(-)

M lib/funweb.js
M lib/logger.js
A lib/mwadapt.js
M lib/funweb.js => lib/funweb.js +12 -9
@@ 6,13 6,14 @@ const cors = require('cors')
  const pug = require('pug')
  const logger = require('./logger')
+ const adapt = require('./mwadapt')
  
  // need some automatic generation of forms/html from code (can be fully controlled with templates or jsx, or auto-generated using a distinct library)
  // TODO: make the canonical middleware signature (next, req, res) so it can be curried more easily? Or even (next, [req, res])?
  
  // status and body helper
  const handler = (status, body) => R.pipe(
-   R.nthArg(1),
+   R.last,
    R.invoker(1, 'writeHead')(status),
    R.invoker(1, 'end')(body)
  )


@@ 29,6 30,7 @@ { basedir: tpldir }
  )
  const helloParams = R.pipe(
+   R.head,
    R.prop('url'),
    R.split('/'),
    R.filter(R.pipe(R.isEmpty, R.not)),


@@ 39,20 41,21 @@ const helloBody = R.pipe(helloParams, pugHello)
  
  // map routes to handlers
- const route = (url) => R.pipe(R.prop('url'), R.startsWith(url))
+ const route = (url) => R.pipe(R.head, R.prop('url'), R.startsWith(url))
  const routes = R.cond([
-   [route('/hello'), (req, res) => handler(200, helloBody(req))(req, res)],
+   [route('/hello'), ([req, res]) => handler(200, helloBody(req))(req, res)],
    [route('/nothello'), handler(200, 'NOT HELLO!')],
    [R.T, serveOrNotFound]
  ])
  
+ /*
  // middleware
- const logAndNext = (req, res) => logger(req, res, R.thunkify(routes)(req, res))
- const compress = compression()
- const compressAndNext = (req, res) => compress(req, res, R.thunkify(logAndNext)(req, res))
+ const compress = adapt(compression())
+ console.log(compress.length)
  // TODO: configure CORS properly for the application's needs
- const corsFn = cors()
- const corsAndNext = (req, res) => corsFn(req, res, R.thunkify(compressAndNext)(req, res))
+ const corsFn = adapt(cors())
+ const app = R.pipe(R.pair, corsFn(compress(logger(routes))))
+ */
  
  // start server
  const logAddress = R.pipe(


@@ 61,5 64,5 @@ R.join(':'),
    (addr) => console.log(`listening on ${addr}...`)
  )
- const server = http.createServer(corsAndNext)
+ const server = http.createServer(R.pipe(R.pair, R.curry(logger)(routes)))
  server.listen(3000, '127.0.0.1', () => logAddress(server))

M lib/logger.js => lib/logger.js +4 -2
@@ 1,6 1,8 @@-function logger (req, res, next)  {
+ const R = require('ramda')
+ 
+ function logger (next, [req, res]) {
    const start = Date.now()
-   const val = next(req, res)
+   const val = next([req, res])
    const end = Date.now()
    // TODO: should take a Writable stream as argument
    console.log(`url=${req.url} status=${res.statusCode} duration=${end - start}ms`)

A lib/mwadapt.js => lib/mwadapt.js +14 -0
@@ 0,0 1,14 @@
+ const R = require('ramda')
+ 
+ function middleware (fn, next, [req, res]) {
+   return fn(req, res, R.thunkify(next)(req, res))
+ }
+ 
+ // takes a fn that accepts the usual connect middleware arguments
+ // (req, res, next), where next is nullary, and converts it to the
+ // (next, [req, res]) signature, as a curried function.
+ function adapt (fn) {
+   return R.curry(middleware)(fn)
+ }
+ 
+ module.exports = adapt