diff --git a/reactor.js b/reactor.js index 975f90a..6e4c240 100644 --- a/reactor.js +++ b/reactor.js @@ -32,11 +32,12 @@ var typer = require('content-type') var arrayed = require('./arrayed') -function Constructor (object, dispatch) { +function Constructor (object, dispatch, turnstile) { this._object = object this._dispatch = dispatch this._use = [] this._defaultUse = true + this.turnstile = turnstile this.logger = function (entry) { if (entry.error) { console.log(entry.error.stack) @@ -63,6 +64,12 @@ Constructor.prototype.use = function () { } } +Constructor.prototype.routes = function (routes) { + for (var key in routes) { + this.dispatch(key, routes[key]) + } +} + Constructor.prototype.dispatch = function () { var vargs = [] vargs.push.apply(vargs, arguments) @@ -108,14 +115,10 @@ function handler (queue, before, operation) { } } -function Reactor (object, configurator) { - var constructor = new Constructor(object, this._dispatch = {}) +function Reactor (object, configurator, turnstile) { + this.turnstile = turnstile || new Turnstile + var constructor = new Constructor(object, this._dispatch = {}, this.turnstile) configurator(constructor) - this.turnstile = new Turnstile({ - Date: coalesce(constructor.Date, Date), - turnstiles: coalesce(constructor.turnstiles, 24), - timeout: coalesce(constructor.timeout) - }) this._queue = new Turnstile.Queue(this, '_respond', this.turnstile) this._logger = constructor.logger this._completed = coalesce(constructor.completed, noop) @@ -131,7 +134,7 @@ function Reactor (object, configurator) { for (var pattern in this._dispatch) { dispatcher[pattern] = handler(this._queue, before, this._dispatch[pattern]) } - this.middleware = require('connect')().use(dispatch(dispatcher)) + this.middleware = require('connect')().use(this._middleware = dispatch(dispatcher)) } Reactor.prototype._canceled = cadence(function () { throw 503 }) @@ -293,6 +296,22 @@ Reactor.prototype._respond = cadence(function (async, envelope) { }) }) +Reactor.json = function () { + return require('body-parser').json({ limit: '64mb' }) +} + +Reactor.auth = function () { + return require('express-auth-parser') +} + +Reactor.urlencoded = function () { + return require('body-parser').urlencoded({ extended: false, limit: '64mb' }) +} + +Reactor.reactor = function (object, configure, turnstile) { + return new Reactor(object, configure, turnstile)._middleware +} + Reactor.resend = function (statusCode, headers, body) { return Reactor.send({ statusCode: statusCode, headers: headers }, body) } diff --git a/t/reactor.t.js b/t/reactor.t.js index 9fb1345..e5eb6c7 100644 --- a/t/reactor.t.js +++ b/t/reactor.t.js @@ -9,15 +9,14 @@ function prove (async, okay) { var coalesce = require('extant') var stream = require('stream') + var Turnstile = require('turnstile') + // Defaults, but we call the default functions below as well. new Reactor(this, function (constructor) {}) var now = 0, logs = [] function Service () { this.reactor = new Reactor(this, function (constructor) { - constructor.turnstiles = 1 - constructor.timeout = 5 - var logger = constructor.logger constructor.logger = function (entry) { if (logs.length != 0) { @@ -27,8 +26,6 @@ function prove (async, okay) { logger(entry) } - constructor.Date = { now: function () { return now } } - constructor.useDefault() constructor.use([ function (request, response, next) { next() @@ -46,7 +43,11 @@ function prove (async, okay) { constructor.dispatch('GET /callbacky', 'callbacky') constructor.dispatch('GET /resources/:id', 'resource') constructor.dispatch('POST /post', 'post') - }) + }, new Turnstile({ + Date: { now: function () { return now } }, + turnstiles: 1, + timeout: 5 + })) } Service.prototype.index = cadence(function () { diff --git a/t/shorthand.t.js b/t/shorthand.t.js index d14e307..0e5a298 100644 --- a/t/shorthand.t.js +++ b/t/shorthand.t.js @@ -7,12 +7,56 @@ function prove (okay, callback) { destructible.completed.wait(callback) var connect = require('connect') + var Reactor = require('..') var cadence = require('cadence') + var delta = require('delta') + + var http = require('http') + + var UserAgent = require('vizsla') + var ua = new UserAgent cadence(function (async) { async(function () { - }, function () { + // Maybe `turnstile` is exposed as a property of the request? That + // way you can log it in response to a `curl`. Could also expose it + // to the logger itself as a second property, but then why not place + // it in . + var app = connect() + .use(Reactor.json()) + .use(Reactor.auth()) + .use(Reactor.urlencoded()) + .use(Reactor.reactor({ + object: 0 + }, function (configurator) { + configurator.turnstile.health.turnstiles = 24 + setInterval(function () { + console.log('turnstile', configurator.turnstile.health) + }, 1000).unref() + configurator.routes({ + 'GET /': cadence(function () { + return [ { 'content-type': 'text/plain' }, 'API Index\n' ] + }) + }) + configurator.logger = function (entry) { + console.log(entry) + } + })) + var server = http.createServer(app) + async(function () { + server.listen(8888) + delta(async()).ee(server).on('listening') + }, [function () { + server.close() + }], function () { + ua.fetch({ + url: 'http://127.0.0.1:8888/', + parse: 'text' + }, async()) + }, function (body) { + okay(body, 'API Index\n', 'got') + }) }) })(destructible.durable('test')) }