Giter Club home page Giter Club logo

8track's People

Contributors

jeffrey-lin avatar jrf0110 avatar robertcepa avatar third774 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

8track's Issues

Support for multiple HTMLRewriters

Since the HTMLRewriter API's .transform(res) returns a new Response instance, this makes working with middleware difficult. I suggest a new ctx method which collects all transforms until the response is handled:

// Transform all HTML responses at /foo such that:
// <h1>Bar</h1><h2>Baz</h2>
app.all`/foo`
  .use((ctx, next) => {
    ctx.transform().on('h1', { text: node => node.replace('Bar') })
    return next()
  })
  .use((ctx, next) => {
    ctx.transform().on('h2', { text: node => node.replace('Baz') })
    return next()
  })
  .handle(ctx => ctx.html('<h1>Foo</h1><h2>Bar</h2>'))

The transforms here don't work like streams piping into one-another, but rather like a single transform instance.

Generic Edge Cache Middleware

It shouldn't matter where the Response came from, the edge cache middleware should be able to cache it and serve it early in the middleware chain.

// These would be our cache middleware options
type CacheOptions = {
  getCacheKey?: (req: URL) => string
  cache?: typeof caches.default
  edgeTTL?: number
  browserTTL?: number
  edgeTTLForHTML?: number
  browserTTLForHTML?: number
  allowedMethods?: Method[] 
}

import { Router, cache } from '8track'

const app = new Router()

// Cache all GET requests
app.get`(.*)`.use(cache())
...

Please can you use semver?

The changes introduced by #23 and related PRs are not backward compatible and should have resulted in a major version bump; which would have prevented npm/yarn from upgrading the dependency on 8track and breaking our application.

Could you please consider using semver so that breaking changes are properly identified in the future?

Add an easier way to handle requests

Right now, the glue code required for consumers is pretty significant:

import { getErrorPageHTML } from '8track';
import { router } from './router';

addEventListener('fetch', event => {
  const res = router.getResponseForEvent(event).catch(error => {
    return new Response(getErrorPageHTML(event.request, error), {
      status: 500,
      headers: {
        'Content-Type': 'text/html',
      },
    });
  });

  event.respondWith(res as any);
});

ctx.end(...) causes afterware effects to be ignored

Edit

I previously thought this was only the case for ctx.end(new Response()). However, this applies to any afterware effects

For instance:

app.get(`(.*)`).use(async (ctx, next) => {
  await next()
  ctx.response.headers.append('Hello', 'World')
}).handle(async ctx => ctx.end(new Response('Hi'))

The 'Hello: World' Header will not make it into the final response. This is due to ctx being a different instance from middleware to middleware.

I originally had this ticket slated for a V2 release, but I think it's buggy enough to make it into 1.x as well.

Original

Suppose you have some middleware which adds a header and some route handler which calls .end() with a new Response::

app.get(`(.*)`).use(async (ctx, next) => {
  ctx.response.headers.append('Hello', 'World')
  return next()
}).handle(async ctx => ctx.end(new Response('Hi'))

This is confusing but not entirely surprising since the new Response will override the old response and not get any headers. There should be a way for middlewares and handlers to compose nicely and have responses merged together.

8track behaves a bit differently than koa in that the response is not sent until after all middleware chains have unwound. This should be fixed in #42.

Until then, one could add the header appending after an await next(), but this confusing to me - Why should the response be editable after that point? Similarly, HTMLRewriter becomes unviable after response becomes immutable after await next().

I propose we do a couple of things to make this nicer:

  1. Add a new property headers on ctx which will collect headers in a context and merge them with the final response
  2. Add a new method .transform() which accepts an HTMLRewriter instance. Transforms will be collected and merged with the final response

I built something similar

Hey jrf0110,

I built a similar framework, perhaps it can serve as an inspiration. It also features typed (optional) path parameters, but it does it without the need for literal strings (perhaps this is on your to-do list too?). Here's a GIF

XeOyoxF

It also allows you to type the state (what you call ctx.data) a handler/middleware expects and will throw a type error if you get it wrong, I think that's possible here too? That part is not super elegant though..

Check it the intro post here, curious to hear your thoughts!

Support sub-router mounting

import { Router } from '8track'

const router = new Router()
const usersRouter = new Router()

usersRouter.get`/`.handle(async ctx => {
  // List users
})

usersRouter.post`/`.handle(async ctx => {
  // Create user
})

usersRouter.get`/${'userId'}`.handle(async ctx => {
  // Get user by ID
})

usersRouter.put`/${'userId'}`.handle(async ctx => {
  // Update user by ID
})

usersRouter.del`/${'userId'}`.handle(async ctx => {
  // Delete user by ID
})

router.all`/organization/${'organizationId'}/users`.use(usersRouter.routes())

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.