Skip to content

Commit cab04c5

Browse files
authored
Merge branch 'main' into elysia-tailwind
2 parents f30ae5f + a852cbc commit cab04c5

File tree

6 files changed

+315
-42
lines changed

6 files changed

+315
-42
lines changed

docs/.vitepress/config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,18 @@ export default defineConfig({
290290
text: 'JWT',
291291
link: '/plugins/jwt'
292292
},
293+
{
294+
text: 'Server Timing',
295+
link: '/plugins/server-timing'
296+
},
293297
{
294298
text: 'Static',
295299
link: '/plugins/static'
296300
},
301+
{
302+
text: 'Stream',
303+
link: '/plugins/stream'
304+
},
297305
{
298306
text: 'Swagger',
299307
link: '/plugins/swagger'

docs/plugins/overview.md

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ head:
77

88
- - meta
99
- name: 'description'
10-
content: Elysia is designed to be modular and lightweight. That's why Elysia is creating pre-built common pattern plugin for convenient usage for developers, and thanks to community plugins for customizing Elysia even further.
10+
content: Elysia is designed to be modular and lightweight, which is why Elysia includes pre-built plugins involving common patterns for convenient developer usage. Elysia is enhanced by community plugins which customize it even further.
1111

1212
- - meta
1313
- name: 'og:description'
14-
content: Elysia is designed to be modular and lightweight. That's why Elysia is creating pre-built common pattern plugin for convenient usage for developers, and thanks to community plugins for customizing Elysia even further.
14+
content: Elysia is designed to be modular and lightweight, which is why Elysia includes pre-built plugins involving common patterns for convenient developer usage. Elysia is enhanced by community plugins which customize it even further.
1515
---
1616

1717
# Overview
@@ -21,51 +21,51 @@ Following the same idea as Arch Linux (btw, I use Arch):
2121

2222
> Design decisions are made on a case-by-case basis through developer consensus
2323
24-
To ensure that developers endup with performant web server they intent to created.
25-
26-
That's why Elysia is creating pre-built common pattern plugin for convinient usage for developers:
24+
This is to ensure developers end up with a performant web server they intend to create. By extension, Elysia includes pre-built common pattern plugins for convenient developer usage:
2725

2826
## Official plugins:
29-
- [Bearer](/plugins/bearer) - retreiving Bearer token automatically
30-
- [CORS](/plugins/cors) - setup Cross Origin Request request
31-
- [Cron](/plugins/cron) - setup cronjob
32-
- [Eden](/plugins/eden/overview) - end-to-end type safe client for Elysia
33-
- [GraphQL Apollo](/plugins/graphql-apollo) - run GraphQL Apollo on Elysia
34-
- [GraphQL Yoga](/plugins/graphql-yoga) - run GraphQL Yoga on Elysia
35-
- [HTML](/plugins/html) - convenient plugin for handling HTML response
36-
- [JWT](/plugins/jwt) - authentication with JWT
37-
- [Static](/plugins/static) - serve static file/folders
38-
- [Swagger](/plugins/swagger) - generate Swagger documentation in 1 line
39-
- [tRPC](/plugins/trpc) - add tRPC support
40-
- [WebSocket](/patterns/websocket) - websocket support
27+
- [Bearer](/plugins/bearer) - retrieve [Bearer](https://swagger.io/docs/specification/authentication/bearer-authentication/) token automatically
28+
- [CORS](/plugins/cors) - set up [Cross-origin resource sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
29+
- [Cron](/plugins/cron) - set up [cron](https://en.wikipedia.org/wiki/Cron) job
30+
- [Eden](/plugins/eden/overview) - end-to-end type safety client for Elysia
31+
- [GraphQL Apollo](/plugins/graphql-apollo) - run [Apollo GraphQL](https://www.apollographql.com/) on Elysia
32+
- [GraphQL Yoga](/plugins/graphql-yoga) - run [GraphQL Yoga](https://github.com/dotansimha/graphql-yoga) on Elysia
33+
- [HTML](/plugins/html) - handle HTML responses
34+
- [JWT](/plugins/jwt) - authenticate with [JWTs](https://jwt.io/)
35+
- [Server Timing](/plugins/server-timing) - audit performance bottlenecks with the [Server-Timing API](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing)
36+
- [Static](/plugins/static) - serve static files/folders
37+
- [Stream](/plugins/stream) - integrate response streaming and [server-sent events (SSEs)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)
38+
- [Swagger](/plugins/swagger) - generate [Swagger](https://swagger.io/) documentation
39+
- [tRPC](/plugins/trpc) - support [tRPC](https://trpc.io/)
40+
- [WebSocket](/patterns/websocket) - support [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
4141

4242
## Community plugins:
43-
- [Lucia Auth](https://github.com/pilcrowOnPaper/lucia) - Authentication, simple and clean
44-
- [Elysia Clerk](https://github.com/wobsoriano/elysia-clerk) - Unofficial Clerk plugin for ElysiaJS
45-
- [Elysia Polyfills](https://github.com/bogeychan/elysia-polyfills) - run Elysia ecosystem on Node and Deno
46-
- [Vite](https://github.com/timnghg/elysia-vite) - Simple Elysia plugin that helps you use Vite. It serve your entry html file with Vite's scripts injected
47-
- [Elysia Helmet](https://github.com/DevTobias/elysia-helmet) - secure Elysia apps with various HTTP headers.
48-
- [Vite Plugin SSR](https://github.com/timnghg/elysia-vite-plugin-ssr) - Vite Plugin SSR using Elysia server
43+
- [Lucia Auth](https://github.com/pilcrowOnPaper/lucia) - authentication, simple and clean
44+
- [Elysia Clerk](https://github.com/wobsoriano/elysia-clerk) - unofficial Clerk authentication plugin
45+
- [Elysia Polyfills](https://github.com/bogeychan/elysia-polyfills) - run Elysia ecosystem on Node.js and Deno
46+
- [Vite](https://github.com/timnghg/elysia-vite) - serve entry HTML file with Vite's scripts injected
47+
- [Elysia Helmet](https://github.com/DevTobias/elysia-helmet) - secure Elysia apps with various HTTP headers
48+
- [Vite Plugin SSR](https://github.com/timnghg/elysia-vite-plugin-ssr) - Vite SSR plugin using Elysia server
4949
- [OAuth2](https://github.com/bogeychan/elysia-oauth2) - handle OAuth 2.0 authorization code flow
50-
- [Rate Limit](https://github.com/rayriffy/elysia-rate-limit) - simple lightweight rate limiter
51-
- [Logysia](https://github.com/tristanisham/logysia) - classic logging elysia middleware
52-
- [Logger](https://github.com/bogeychan/elysia-logger) - pino logging elysia middleware
53-
- [Elysia Lambda](https://github.com/TotalTechGeek/elysia-lambda) - deploy Elysia on AWS Lambda
54-
- [Decorators](https://github.com/gaurishhs/elysia-decorators) - use typescript decorators with elysia
55-
- [Autoroutes](https://github.com/wobsoriano/elysia-autoroutes) - file system routes for Elysia
56-
- [Group Router](https://github.com/itsyoboieltr/elysia-group-router) - file system and folder-based router for groups.
57-
- [Basic Auth](https://github.com/itsyoboieltr/elysia-basic-auth) - basic http authentication for Elysia.
58-
- [ETag](https://github.com/bogeychan/elysia-etag) - automatic HTTP ETags generation for Elysia.
59-
- [Basic Auth](https://github.com/eelkevdbos/elysia-basic-auth) - Basic http authentication for Elysia (using 'request' event).
60-
- [i18n](https://github.com/eelkevdbos/elysia-i18next) - i18n wrapper for Elysia based on i18next
61-
- [Elysia Request ID](https://github.com/gtramontina/elysia-requestid) - Adds/Forwards request IDs (`X-Request-ID` or custom).
62-
- [Elysia HTMX](https://github.com/gtramontina/elysia-htmx) - Context helpers for [HTMX](https://htmx.org/).
50+
- [Rate Limit](https://github.com/rayriffy/elysia-rate-limit) - simple, lightweight rate limiter
51+
- [Logysia](https://github.com/tristanisham/logysia) - classic logging middleware
52+
- [Logger](https://github.com/bogeychan/elysia-logger) - [pino](https://github.com/pinojs/pino)-based logging middleware
53+
- [Elysia Lambda](https://github.com/TotalTechGeek/elysia-lambda) - deploy on AWS Lambda
54+
- [Decorators](https://github.com/gaurishhs/elysia-decorators) - use TypeScript decorators
55+
- [Autoroutes](https://github.com/wobsoriano/elysia-autoroutes) - filesystem routes
56+
- [Group Router](https://github.com/itsyoboieltr/elysia-group-router) - filesystem and folder-based router for groups
57+
- [Basic Auth](https://github.com/itsyoboieltr/elysia-basic-auth) - basic HTTP authentication
58+
- [ETag](https://github.com/bogeychan/elysia-etag) - automatic HTTP [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) generation
59+
- [Basic Auth](https://github.com/eelkevdbos/elysia-basic-auth) - basic HTTP authentication (using `request` event)
60+
- [i18n](https://github.com/eelkevdbos/elysia-i18next) - [i18n](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n) wrapper based on [i18next](https://www.i18next.com/)
61+
- [Elysia Request ID](https://github.com/gtramontina/elysia-requestid) - add/forward request IDs (`X-Request-ID` or custom)
62+
- [Elysia HTMX](https://github.com/gtramontina/elysia-htmx) - context helpers for [HTMX](https://htmx.org/)
63+
- [Elysia HMR HTML](https://github.com/gtrabanco/elysia-hmr-html) - reload HTML files when changing any file in a directory
64+
- [Elysia Inject HTML](https://github.com/gtrabanco/elysia-inject-html) - inject HTML code in HTML files
65+
- [Elysia HTTP Error](https://github.com/yfrans/elysia-http-error) - return HTTP errors from Elysia handlers
66+
- [Elysia Http Status Code](https://github.com/sylvain12/elysia-http-status-code) - integrate HTTP status codes
67+
- [NoCache](https://github.com/gaurishhs/elysia-nocache) - disable caching
6368
- [Elysia Tailwind](https://github.com/gtramontina/elysia-tailwind) - Compile [Tailwindcss](https://tailwindcss.com/) in a plugin.
64-
- [Elysia HMR HTML](https://github.com/gtrabanco/elysia-hmr-html) - Reload html files when change any file in a directory
65-
- [Elysia Inject HTML](https://github.com/gtrabanco/elysia-inject-html) - So simple plugin to inject HTML code in HTML files
66-
- [Elysia HTTP Error](https://github.com/yfrans/elysia-http-error) - Easiest way to return HTTP errors from Elysia handlers
67-
- [Elysia Http Status Code](https://github.com/sylvain12/elysia-http-status-code) - Simple http status code plugin for Elysia.js
68-
- [NoCache](https://github.com/gaurishhs/elysia-nocache) - A plugin for Elysia to disable caching
6969

7070
---
71-
If you have plugin written for Elysia, feels free to share you plugin by creating PR to [documentation repo](https://github.com/elysiajs/documentation).
71+
If you wrote a plugin for Elysia, feel free to share it by creating a PR on the [documentation repo](https://github.com/elysiajs/documentation).

docs/plugins/server-timing.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
title: Server Timing Plugin - ElysiaJS
3+
head:
4+
- - meta
5+
- property: 'og:title'
6+
content: Server Timing Plugin - ElysiaJS
7+
8+
- - meta
9+
- name: 'description'
10+
content: Plugin for Elysia for performance audit via Server Timing API. Start by installing the plugin with "bun add @elysiajs/server-timing".
11+
12+
- - meta
13+
- name: 'og:description'
14+
content: Plugin for Elysia that add support for streaming response and Server Sent Event, eg. OpenAI integration. Start by installing the plugin with "bun add @elysiajs/server-timing".
15+
---
16+
17+
# Server Timing Plugin
18+
This plugin add support for auditing performance bottleneck with Server Timing API
19+
20+
Install with:
21+
```bash
22+
bun add @elysiajs/server-timing
23+
```
24+
25+
Then use it:
26+
```typescript
27+
import { Elysia } from 'elysia'
28+
import { serverTiming } from '@elysiajs/server-timing'
29+
30+
new Elysia()
31+
.use(serverTiming())
32+
.get('/', () => 'hello')
33+
.listen(8080)
34+
```
35+
36+
Server Timing then will append header 'Server-Timing' with log duration, function name and detail for each life-cycle function.
37+
38+
To inspect, open browser developer tools > Network > [Request made through Elysia server] > Timing.
39+
40+
![Developer tools showing Server Timing screenshot](/assets/server-timing.webp)
41+
42+
Now you can effortlessly audit performance bottleneck of your server.
43+
44+
## Config
45+
Below is a config which is accepted by the plugin
46+
47+
### enabled
48+
@default `NODE_ENV !== 'production'`
49+
50+
Determine whether or not Server Timing should be enabled
51+
52+
### allow
53+
@default `undefined`
54+
55+
A condition whether server timing should be log
56+
57+
### trace
58+
@default `undefined`
59+
60+
Allow Server Timing to log specified life-cycle events:
61+
62+
Trace accepts object of the following:
63+
- request: capture duration from request
64+
- parse: capture duration from parse
65+
- transform: capture duration from transform
66+
- beforeHandle: capture duration from beforeHandle
67+
- handle: capture duration from handle
68+
- afterHandle: capture duration from afterHandle
69+
- total: capture total duration from start to finish
70+
71+
## Pattern
72+
Below you can find the common patterns to use the plugin.
73+
74+
- [Allow Condition](#allow-condition)
75+
76+
## Allow Condition
77+
You may disabled Server Timing on specific route via `allow` property
78+
79+
```ts
80+
import { Elysia } from 'elysia'
81+
import { serverTiming } from '@elysiajs/server-timing'
82+
83+
new Elysia()
84+
.use(
85+
serverTiming({
86+
allow: ({ request }) => {
87+
return new URL(request.url).pathname !== '/no-trace'
88+
}
89+
})
90+
)
91+
```

docs/plugins/static.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ Set response headers of files
8585
## Pattern
8686
Below you can find the common patterns to use the plugin.
8787

88+
- [Single File](#single-file)
89+
8890
## Single file
8991
Suppose you want to return just a single file, you can use `Bun.file` instead of using static plugin
9092
```typescript

docs/plugins/stream.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
title: Stream Plugin - ElysiaJS
3+
head:
4+
- - meta
5+
- property: 'og:title'
6+
content: Stream Plugin - ElysiaJS
7+
8+
- - meta
9+
- name: 'description'
10+
content: Plugin for Elysia that add support for streaming response and Server Sent Event, eg. OpenAI integration. Start by installing the plugin with "bun add @elysiajs/stream".
11+
12+
- - meta
13+
- name: 'og:description'
14+
content: Plugin for Elysia that add support for streaming response and Server Sent Event, eg. OpenAI integration. Start by installing the plugin with "bun add @elysiajs/stream".
15+
---
16+
17+
# Stream Plugin
18+
This plugin add support for streaming response or sending Server Sent Event back to client.
19+
20+
Install with:
21+
```bash
22+
bun add @elysiajs/stream
23+
```
24+
25+
Then use it:
26+
```typescript
27+
import { Elysia } from 'elysia'
28+
import { Stream } from '@elysiajs/stream'
29+
30+
new Elysia()
31+
.get('/', () => new Stream(async (stream) => {
32+
stream.send('hello')
33+
34+
await stream.wait(1000)
35+
stream.send('world')
36+
37+
stream.close()
38+
}))
39+
.listen(8080)
40+
```
41+
42+
By default, `Stream` will return `Response` with `content-type` of `text/event-stream; charset=utf8`.
43+
44+
## Constructor
45+
Below is the constructor parameter accept by `Stream`:
46+
1. Stream:
47+
- Automatic: Automatically stream response from provided value
48+
- Iterable
49+
- AsyncIterable
50+
- ReadableStream
51+
- Response
52+
- Manual: Callback of `(stream: this) => unknown` or `undefined`
53+
2. Options: `StreamOptions`
54+
- [event](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event): A string identifying the type of event described
55+
- [retry](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#retry): The reconnection time in milliseconds
56+
57+
## Method
58+
Below is the method provided by `Stream`:
59+
60+
### send
61+
Enqueue data to stream to send back to client
62+
63+
### close
64+
Close the stream
65+
66+
### wait
67+
Return a promise that resolved in provided value in ms
68+
69+
### value
70+
Inner value of the `ReadableStream`
71+
72+
## Pattern
73+
Below you can find the common patterns to use the plugin.
74+
- [OpenAI](#openai)
75+
- [Fetch Stream](#fetch-stream)
76+
- [Server Sent Event](#server-sent-event)
77+
78+
## OpenAI
79+
Automatic mode is triggered when parameter is either `Iterable` or `AsyncIterable` streaming response back to client automatically.
80+
81+
Below is the example to integrate ChatGPT to Elysia.
82+
83+
```ts
84+
new Elysia()
85+
.get(
86+
'/ai',
87+
({ query: { prompt } }) =>
88+
new Stream(
89+
openai.chat.completions.create({
90+
model: 'gpt-3.5-turbo',
91+
stream: true,
92+
messages: [{
93+
role: 'user',
94+
content: prompt
95+
}]
96+
})
97+
)
98+
)
99+
```
100+
101+
By default [openai](https://npmjs.com/package/openai) chatGPT completion return `AsyncIterable` so you should be able to wrap the OpenAI in `Stream`.
102+
103+
## Fetch Stream
104+
You can pass a fetch from an endpoint that returns the stream to proxy a stream.
105+
106+
This is useful for those endpoints that use AI text-generation since you can proxy it directly, eg. [Cloudflare AI](https://developers.cloudflare.com/workers-ai/models/llm/#examples---chat-style-with-system-prompt-preferred).
107+
```ts
108+
const model = '@cf/meta/llama-2-7b-chat-int8'
109+
const endpoint = `https://api.cloudflare.com/client/v4/accounts/${process.env.ACCOUNT_ID}/ai/run/${model}`
110+
111+
new Elysia()
112+
.get('/ai', ({ query: { prompt } }) =>
113+
fetch(endpoint, {
114+
method: 'POST',
115+
headers: {
116+
authorization: `Bearer ${API_TOKEN}`,
117+
'content-type': 'application/json'
118+
},
119+
body: JSON.stringify({
120+
messages: [
121+
{ role: 'system', content: 'You are a friendly assistant' },
122+
{ role: 'user', content: prompt }
123+
]
124+
})
125+
})
126+
)
127+
```
128+
129+
## Server Sent Event
130+
Manual mode is triggered when parameter is either `callback` or `undefined`, allowing you to control the stream.
131+
132+
### callback-based
133+
Below is an example to create Server Sent Event endpoint using constructor callback
134+
135+
```ts
136+
new Elysia()
137+
.get('/source', () =>
138+
new Stream((stream) => {
139+
const interval = setInterval(() => {
140+
stream.send('hello world')
141+
}, 500)
142+
143+
setTimeout(() => {
144+
clearInterval(interval)
145+
stream.close()
146+
}, 3000)
147+
})
148+
)
149+
```
150+
151+
### value-based
152+
Below is an example to create Server Sent Event endpoint using value-based
153+
154+
```ts
155+
new Elysia()
156+
.get('/source', () => {
157+
const stream = new Stream()
158+
159+
const interval = setInterval(() => {
160+
stream.send('hello world')
161+
}, 500)
162+
163+
setTimeout(() => {
164+
clearInterval(interval)
165+
stream.close()
166+
}, 3000)
167+
168+
return stream
169+
})
170+
```
171+
172+
Both callback-based and value-based stream work in the same way but with just difference syntax for your preference.

docs/public/assets/server-timing.webp

-7.81 KB
Binary file not shown.

0 commit comments

Comments
 (0)