Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Feb 28 2018 04:17

    DylanPiercey on v7.0.4

    (compare)

  • Feb 28 2018 04:17

    DylanPiercey on master

    Improve typings. 7.0.4 (compare)

  • Feb 27 2018 07:44

    DylanPiercey on v7.0.3

    (compare)

  • Feb 27 2018 07:44

    DylanPiercey on master

    Add type definitions for tls op… 7.0.3 (compare)

  • Feb 27 2018 05:51

    DylanPiercey on platform-agnostic

    (compare)

  • Feb 27 2018 05:51

    DylanPiercey on file-size

    (compare)

  • Feb 27 2018 05:51

    DylanPiercey on add-code-of-conduct-1

    (compare)

  • Nov 20 2017 03:11

    DylanPiercey on v7.0.2

    (compare)

  • Nov 20 2017 03:11

    DylanPiercey on master

    Update size in readme 7.0.2 (compare)

  • Nov 19 2017 02:31

    DylanPiercey on v7.0.1

    (compare)

  • Nov 19 2017 02:31

    DylanPiercey on master

    * Update example links in readm… 7.0.1 (compare)

  • Nov 18 2017 04:31

    DylanPiercey on master

    * Update changelog. * Release 7… 7.0.0 (compare)

  • Nov 18 2017 04:31

    DylanPiercey on v7.0.0

    (compare)

  • Nov 18 2017 04:00

    DylanPiercey on v7.0.0-rc.12

    (compare)

  • Nov 18 2017 04:00

    DylanPiercey on master

    Remove default of 404 on status… 7.0.0-rc.12 (compare)

  • Nov 12 2017 18:53

    DylanPiercey on master

    * Organize types in namespace. … 7.0.0-rc.11 (compare)

  • Nov 12 2017 18:53

    DylanPiercey on v7.0.0-rc.11

    (compare)

  • Nov 11 2017 18:34

    DylanPiercey on master

    * Switch back to default export… 7.0.0-rc.10 (compare)

  • Nov 11 2017 18:34

    DylanPiercey on v7.0.0-rc.10

    (compare)

  • Oct 24 2017 00:00

    DylanPiercey on v7.0.0-rc.9

    (compare)

Dylan Piercey
@DylanPiercey
Gotcha. Curious to see what those bridges looked like. I believe you can mount Rill apps in express like so:
const eapp = express()
const rapp = rill()
rapp
    .use(...)
    .get(...)

express
    .use(...)
    .get(...)
    .use(rapp.handler())
    .listen(...)
Constance Okoghenun
@okoghenun
Didn't know we could do that, Plus express middlewares typically receive 3 parameters as against 2 for Rill, so we wrote a helper that will take Rills (ctx, next) => {...} and transform to (req, res, next) => {...} which our express middlewares were already expecting
Dylan Piercey
@DylanPiercey

Ah ic. Yeah Rill has a much closer API to koa but not exactly. The main reason I decided to make it different is because in most cases you shouldn't just take your existing middleware and use it in the browser since typically there are native dependencies and assumptions made in most server side middleware.

When I get home later today I'll double check the mounting of a rill app in Express, I know I've done it before but can't quite remember the syntax.

Constance Okoghenun
@okoghenun
That would be awesome! I'd be looking forward to it
Dylan Piercey
@DylanPiercey
Just tested it out and the method mentioned above seems to work fine for mounting Rill apps inside express apps :).
Might simplify things a little bit for you, however you'll still need the adapter for spreading the middleware arguments. It may be worth adding a utility like that to the rill org, curious what your thoughts are though?
Samuel
@imolorhe
@DylanPiercey that would be awesome, do people could work with that instead of needing to reinvent the wheel.
Dylan Piercey
@DylanPiercey
@imolorhe I agree, I'll probably try and get something out here soon.
Samuel
@imolorhe
@DylanPiercey we could probably even help out with that. You should put up the sample projects you created to test the rill and express combination too
Dylan Piercey
@DylanPiercey

@imolorhe FTR the goal is to use express middleware with Rill right?

Basically this:

import myExpressMiddleware from '..'

app.use(({ req, res }, next) => {
  return new Promise((resolve, reject) => {
    myExpressMiddleware(args)(res, res, err => {
      if (err) reject(err)
      else resolve(next())
    })
  })
})

Which could be simplified to:

import adapter from '@rill/express-adapter'
import myExpressMiddleware from '..'

app.use(adapter(myExpressMiddleware, args))

Or something like that?

Samuel
@imolorhe
@DylanPiercey Using express middlewares in rill, and also interfacing with the rill app in the same way you would interface with the express app.
For instance, mounting routers using app.use('/route', router), using router.all('/route', middleware), etc.
Dylan Piercey
@DylanPiercey

Regarding making the API the same as Express it's not something I'd consider right now. However both of the things you mentioned can be done like so:

app.at('/route/*', router) and app.at('/route', router) respectively.

Dylan Piercey
@DylanPiercey
Also @imolorhe do you mind posting what your current implementation is for converting express middleware?
Dylan Piercey
@DylanPiercey

Do you think it's worth supporting Express middleware setting headers that could be read by Rill middleware?

Here is my current implementation, which creates a full express request and response.

var express = require('express')
var setProto = require('setprototypeof')
var defaultApp = express()

module.exports = function fromExpress (middleware, app) {
  var config = { app: { configurable: true, enumerable: true, writable: true, value: app || defaultApp } }
  var newReqProto = Object.create(app.request, config)
  var newResProto = Object.create(app.response, config)

  return function (ctx, next) {
    return new Promise((resolve, reject) => {
      var req = ctx.req.original
      var res = ctx.res.original
      var oldReqProto = Object.getPrototypeOf(req)
      var oldResProto = Object.getPrototypeOf(res)

      // Add express prototypes.
      setProto(req, newReqProto)
      setProto(req, newResProto)

      // Execute express middleware.
      middleware(req, res, function (err) {
        if (err) reject(err)
        else if (res.headersSent) resolve()
        else {
          // Restore default http prototypes.
          setProto(req, oldReqProto)
          setProto(res, oldResProto)
          resolve(next())
        }
      })
    })
  }
}

I think it should solve most cases.

Patrick Steele-Idem
@patrick-steele-idem
@DylanPiercey I would worry about the performance overhead of changing the prototype for every request. I feel like that should be done at initialization.
Dylan Piercey
@DylanPiercey
@patrick-steele-idem are you suggesting mutating the native IncomingMessage and ServerResponse protos during init? Also AFAIK this is what express does internally on each request.
It wouldn't be ideal to when you have multiple express middleware being converted though.
Actually I think express does this per middleware as well https://github.com/expressjs/express/blob/master/lib/application.js#L230
Maybe this is why I consistently bench Rill to be much faster than express :p.
Oh actually that was just for mounted apps, but still.
Patrick Steele-Idem
@patrick-steele-idem
Express is an example of what you probably shouldn't do IMO. Monkey-patching has a cost. I'm curious, have you investigated https://github.com/fastify/fastify ?
Dylan Piercey
@DylanPiercey
Yeah I have taken a look a while ago and ran some benches against it but can't quite remember how Rill faired. I also looked at https://github.com/trekjs/trek and I remember that one being pretty close. I'll have to rebench fastify though it seems much more popular now.
Also re the express adapter, I'm not quite sure how else I'd implement this while maintaining support for all of express's apis. Koa would be easy to adapt since it has sensical constructor objects and doesn't patch protos.
Patrick Steele-Idem
@patrick-steele-idem
Yeah, there's probably not a better option if you need to fully support Express, unfortunately. It's too bad you can't monkey-patch the http.IncomingRequest object for a server in cases where you have to do it. The following might be nice:
const server = require('http').createServer();
server.IncomingRequest = class MyIncomingRequest extends http.IncomingRequest { ... };
Dylan Piercey
@DylanPiercey
Yeah that'd be pretty sweet. Although probably better for express to just switch to wrapping a request instead of augmenting existing :p.
Constance Okoghenun
@okoghenun
Hi @DylanPiercey Here is a gist to how we ensure Express routes play nice with Rill https://gist.github.com/okoghenun/cea9edce75e716a0301de697b8ec794a
All we need to do to get Express middleware methods to work for Rill is the do...
let app = rill();
//This guy does the magic of making sure express and rill routes play nice
app = routeTransformer(app);
from there we can call app.put((req, res, next) => {...}) or any other express method
Dylan Piercey
@DylanPiercey
@okoghenun I'm not currently interested in making a express method/api shim, more a shim for individual middleware to be used somewhat sparingly. Although it's cool what you've done.

IE:

const adapt = require('@rill/from-express')
const app = rill()
  .put(adapt((req, res, next) => {}))
  .use(adapt(myOtherExpressMiddleware({ stuff: true }))

But this would be exclusively for server side.

Constance Okoghenun
@okoghenun
Ah I see, along with shimming the Express HTTP verbs (Very important for use case) we shim it's middleware in that function we do ```js
// Create a handler that uses Rill's handler format.
// This would be passed into Rill instead of the original express handlers.
// However it would call the original express handlers with the appropriate arguments it supports
let fxn = (ctx, next) => {
                let nxt = (err) => {
                    if (err) {
                        logger.error(err);
                    }

                    return next(...arguments);
                };

                return handler(ctx.req, ctx.res, nxt);
            };```
You can see that from line 75 of the gist
This basically allows you to use express style code for your middleware
Dylan Piercey
@DylanPiercey

Right, it's a cool idea but I think at that point it would be best to wrap @rill/http instead of Rill. It wouldn't be too hard to fork express and use @rill/http in place of http to achieve a similar result with less overhead and more compatibility.

The reason I haven't done something like this is that I believe using express middleware in the browser can be dangerous because you don't necessarily know if the code is optimized for the browser or server, or if it will even work. With any middleware in the rill-org you are guaranteed that the middleware will work appropriately in both environments.

At every point in the design of Rill's api's and middleware I have been conscious of both browser side ergonomics and server side, while ensuring optimal code is delivered to each environment.
Constance Okoghenun
@okoghenun
@DylanPiercey I agree that using just any express middleware on the browser may not be the best idea but I'm of the opinion that the decision should be left to the developer. For our use case we had already invested a lot in our express codebase and wanted a to reuse the bulk of the components we had written for the server but that would work well on the client
Dylan Piercey
@DylanPiercey
That's fair enough and I'm glad to hear that solution made things easier for you. This is exactly why Rill has the #setup method, where you can do stuff like app.setup(expressAdapter) which is essentially your transformer. I just wouldn't add something like that to the org because I can see it being far to easy for developers (whom in my experience seem to already have a hard time distinguishing client and server with this approach) to shoot themselves in the foot.
Constance Okoghenun
@okoghenun

:laughing:

...whom in my experience seem to already have a hard time distinguishing client and server with this approach

Dylan Piercey
@DylanPiercey
:p
Constance Okoghenun
@okoghenun
We all need to shoot ourselves from time to time :joy:
Dylan Piercey
@DylanPiercey
True, you don't learn otherwise. But I try not to promote it :p.
Lon Ilesanmi
@lon-io
Hi @DylanPiercey
rill-js/delegate#1
Dylan Piercey
@DylanPiercey
This is a bug, I haven't used the delegate module in a while. Will fix today, thanks for bringing it up!
Lon Ilesanmi
@lon-io
Great, thanks!
Lon Ilesanmi
@lon-io
@DylanPiercey That was a very fast 5.0 ship :shipit: :shipit:
Dylan Piercey
@DylanPiercey
😃 I don't mess around 😎
Always feel free to reach out if you have any issues 😄
Lon Ilesanmi
@lon-io
Sure, thanks
Lon Ilesanmi
@lon-io
Hi @DylanPiercey , is this the only way to trigger a page reload routed through rill rather than the server?
https://github.com/DylanPiercey/submit-form/blob/master/client/index.js#L30