hono 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -1
- package/dist/context.d.ts +2 -3
- package/dist/context.js +4 -4
- package/dist/hono.d.ts +0 -1
- package/dist/hono.js +3 -8
- package/dist/index.d.ts +7 -1
- package/dist/index.js +7 -2
- package/dist/middleware/mustache/mustache.d.ts +5 -0
- package/dist/middleware/serve-static/serve-static.d.ts +2 -1
- package/dist/middleware/serve-static/serve-static.js +1 -1
- package/dist/router/trie-router/node.js +1 -0
- package/dist/utils/cloudflare.js +1 -1
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -32,8 +32,14 @@ app.fire()
|
|
|
32
32
|
- **Middleware** - built-in middleware and ability to extend with your own middleware.
|
|
33
33
|
- **TypeScript** - first-class TypeScript support.
|
|
34
34
|
- **Optimized** - for Cloudflare Workers.
|
|
35
|
+
- **Deno** - support for Deno (Experimental).
|
|
35
36
|
|
|
36
|
-
##
|
|
37
|
+
## Benchmarks
|
|
38
|
+
|
|
39
|
+
### Cloudflare Workers
|
|
40
|
+
|
|
41
|
+
- Machine: Apple MacBook Pro, 32 GiB, M1 Pro
|
|
42
|
+
- Scripts: [benchmarks/handle-event](https://github.com/honojs/hono/tree/master/benchmarks/handle-event)
|
|
37
43
|
|
|
38
44
|
**Hono is fastest**, compared to other routers for Cloudflare Workers.
|
|
39
45
|
|
|
@@ -47,6 +53,22 @@ Fastest is hono - regexp-router
|
|
|
47
53
|
✨ Done in 43.56s.
|
|
48
54
|
```
|
|
49
55
|
|
|
56
|
+
### Deno
|
|
57
|
+
|
|
58
|
+
- Machine: Apple MacBook Pro, 32 GiB, M1 Pro, Deno v1.22.0
|
|
59
|
+
- Scripts: [benchmarks/deno](https://github.com/honojs/hono/tree/master/benchmarks/deno)
|
|
60
|
+
- Method: `autocannon -c 100 -d 40 -p 10 'http://127.0.0.1:8000/user/lookup/username/foo'`
|
|
61
|
+
|
|
62
|
+
**Hono is fastest**, compared to other frameworks for Deno.
|
|
63
|
+
|
|
64
|
+
| Framework | Version | Results |
|
|
65
|
+
| ----------------------------- | :-----: | ----------------------------------------: |
|
|
66
|
+
| **Hono - RegExpRouter** | 1.6.0 | **5118k requests in 40.02s, 865 MB read** |
|
|
67
|
+
| **Hono - TriRouter(default)** | 1.6.0 | **4932k requests in 40.02s, 833 MB read** |
|
|
68
|
+
| Faster | 5.7 | 3579k requests in 40.02s, 551 MB read |
|
|
69
|
+
| oak | 10.5.1 | 2385k requests in 40.02s, 403 MB read |
|
|
70
|
+
| opine | 2.2.0 | 1491k requests in 40.02s, 346 MB read |
|
|
71
|
+
|
|
50
72
|
## Why so fast?
|
|
51
73
|
|
|
52
74
|
Routers used in Hono are really smart.
|
|
@@ -734,6 +756,34 @@ export default app
|
|
|
734
756
|
|
|
735
757
|
- Hono Examples - <https://github.com/honojs/examples>
|
|
736
758
|
|
|
759
|
+
## Deno
|
|
760
|
+
|
|
761
|
+
Hono also works with Deno. This feature is still experimental.
|
|
762
|
+
|
|
763
|
+
```tsx
|
|
764
|
+
/** @jsx jsx */
|
|
765
|
+
import { serve } from 'https://deno.land/std@0.146.0/http/server.ts'
|
|
766
|
+
import { Hono, logger, poweredBy, basicAuth, jsx } from 'https://deno.land/x/hono/mod.ts'
|
|
767
|
+
|
|
768
|
+
const app = new Hono()
|
|
769
|
+
|
|
770
|
+
app.use('*', logger(), poweredBy())
|
|
771
|
+
app.get(
|
|
772
|
+
'/auth/*',
|
|
773
|
+
basicAuth({
|
|
774
|
+
username: 'deno',
|
|
775
|
+
password: 'isacool',
|
|
776
|
+
})
|
|
777
|
+
)
|
|
778
|
+
|
|
779
|
+
app.get('/', (c) => {
|
|
780
|
+
return c.html(<h1>Hello Deno!</h1>)
|
|
781
|
+
})
|
|
782
|
+
app.get('/auth/abc', (c) => c.text('You are authorized'))
|
|
783
|
+
|
|
784
|
+
serve(app.fire())
|
|
785
|
+
```
|
|
786
|
+
|
|
737
787
|
## Related projects
|
|
738
788
|
|
|
739
789
|
Implementation of the original router `TrieRouter` is inspired by [goblin](https://github.com/bmf-san/goblin). `RegExpRouter` is inspired by [Router::Boom](https://github.com/tokuhirom/Router-Boom). API design is inspired by [express](https://github.com/expressjs/express) and [koa](https://github.com/koajs/koa). [itty-router](https://github.com/kwhitley/itty-router), [Sunder](https://github.com/SunderJS/sunder), and [worktop](https://github.com/lukeed/worktop) are the other routers or frameworks for Cloudflare Workers.
|
package/dist/context.d.ts
CHANGED
|
@@ -17,8 +17,7 @@ export declare class Context<RequestParamKeyType extends string = string, E = En
|
|
|
17
17
|
private _headers;
|
|
18
18
|
private _res;
|
|
19
19
|
private notFoundHandler;
|
|
20
|
-
|
|
21
|
-
constructor(req: Request<RequestParamKeyType>, env?: E | undefined, eventOrExecutionCtx?: FetchEvent | ExecutionContext | undefined, notFoundHandler?: NotFoundHandler);
|
|
20
|
+
constructor(req: Request, env?: E | undefined, eventOrExecutionCtx?: FetchEvent | ExecutionContext | undefined, notFoundHandler?: NotFoundHandler);
|
|
22
21
|
get res(): Response;
|
|
23
22
|
set res(_res: Response);
|
|
24
23
|
header(name: string, value: string): void;
|
|
@@ -29,7 +28,7 @@ export declare class Context<RequestParamKeyType extends string = string, E = En
|
|
|
29
28
|
newResponse(data: Data | null, status: StatusCode, headers?: Headers): Response;
|
|
30
29
|
body(data: Data | null, status?: StatusCode, headers?: Headers): Response;
|
|
31
30
|
text(text: string, status?: StatusCode, headers?: Headers): Response;
|
|
32
|
-
json(object:
|
|
31
|
+
json<T>(object: T, status?: StatusCode, headers?: Headers): Response;
|
|
33
32
|
html(html: string, status?: StatusCode, headers?: Headers): Response;
|
|
34
33
|
redirect(location: string, status?: StatusCode): Response;
|
|
35
34
|
notFound(): Response | Promise<Response>;
|
package/dist/context.js
CHANGED
|
@@ -8,13 +8,13 @@ class Context {
|
|
|
8
8
|
this._pretty = false;
|
|
9
9
|
this._prettySpace = 2;
|
|
10
10
|
this.req = req;
|
|
11
|
-
|
|
12
|
-
this.env = env;
|
|
13
|
-
}
|
|
14
|
-
this.executionCtx = eventOrExecutionCtx;
|
|
11
|
+
this.env = env ? env : {};
|
|
15
12
|
if (eventOrExecutionCtx && 'respondWith' in eventOrExecutionCtx) {
|
|
16
13
|
this.event = eventOrExecutionCtx;
|
|
17
14
|
}
|
|
15
|
+
else {
|
|
16
|
+
this.executionCtx = eventOrExecutionCtx;
|
|
17
|
+
}
|
|
18
18
|
this.notFoundHandler = notFoundHandler;
|
|
19
19
|
this.finalized = false;
|
|
20
20
|
}
|
package/dist/hono.d.ts
CHANGED
|
@@ -50,6 +50,5 @@ export declare class Hono<E extends Env = Env, P extends string = '/'> extends H
|
|
|
50
50
|
handleEvent(event: FetchEvent): Promise<Response>;
|
|
51
51
|
fetch(request: Request, env?: E, executionCtx?: ExecutionContext): Promise<Response>;
|
|
52
52
|
request(input: RequestInfo, requestInit?: RequestInit): Promise<Response>;
|
|
53
|
-
fire(): void;
|
|
54
53
|
}
|
|
55
54
|
export {};
|
package/dist/hono.js
CHANGED
|
@@ -29,7 +29,7 @@ class Hono extends defineDynamicClass() {
|
|
|
29
29
|
const message = 'Internal Server Error';
|
|
30
30
|
return c.text(message, 500);
|
|
31
31
|
};
|
|
32
|
-
(0, request_1.extendRequestPrototype)();
|
|
32
|
+
(0, request_1.extendRequestPrototype)();
|
|
33
33
|
const allMethods = [...methods, router_1.METHOD_NAME_ALL_LOWERCASE];
|
|
34
34
|
allMethods.map((method) => {
|
|
35
35
|
this[method] = (args1, ...args) => {
|
|
@@ -91,13 +91,13 @@ class Hono extends defineDynamicClass() {
|
|
|
91
91
|
matchRoute(method, path) {
|
|
92
92
|
return this.router.match(method, path);
|
|
93
93
|
}
|
|
94
|
-
async dispatch(request,
|
|
94
|
+
async dispatch(request, eventOrExecutionCtx, env) {
|
|
95
95
|
const path = (0, url_1.getPathFromURL)(request.url, this.strict);
|
|
96
96
|
const method = request.method;
|
|
97
97
|
const result = this.matchRoute(method, path);
|
|
98
98
|
request.paramData = result?.params;
|
|
99
99
|
const handlers = result ? result.handlers : [this.notFoundHandler];
|
|
100
|
-
const c = new context_1.Context(request, env,
|
|
100
|
+
const c = new context_1.Context(request, env, eventOrExecutionCtx, this.notFoundHandler);
|
|
101
101
|
const composed = (0, compose_1.compose)(handlers, this.errorHandler, this.notFoundHandler);
|
|
102
102
|
let context;
|
|
103
103
|
try {
|
|
@@ -124,10 +124,5 @@ class Hono extends defineDynamicClass() {
|
|
|
124
124
|
const req = input instanceof Request ? input : new Request(input, requestInit);
|
|
125
125
|
return this.dispatch(req);
|
|
126
126
|
}
|
|
127
|
-
fire() {
|
|
128
|
-
addEventListener('fetch', (event) => {
|
|
129
|
-
event.respondWith(this.handleEvent(event));
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
127
|
}
|
|
133
128
|
exports.Hono = Hono;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
/// <reference path="request.d.ts" />
|
|
2
|
-
|
|
2
|
+
import { Hono } from './hono';
|
|
3
3
|
export type { Handler, Next } from './hono';
|
|
4
4
|
export { Context } from './context';
|
|
5
5
|
export type { Env } from './context';
|
|
6
|
+
declare module './hono' {
|
|
7
|
+
interface Hono {
|
|
8
|
+
fire(): void;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export { Hono };
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
|
|
3
3
|
/// <reference path="./request.ts" /> Import "declare global" for the Request interface.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.
|
|
6
|
-
|
|
5
|
+
exports.Hono = exports.Context = void 0;
|
|
6
|
+
const hono_1 = require("./hono");
|
|
7
7
|
Object.defineProperty(exports, "Hono", { enumerable: true, get: function () { return hono_1.Hono; } });
|
|
8
8
|
var context_1 = require("./context");
|
|
9
9
|
Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_1.Context; } });
|
|
10
|
+
hono_1.Hono.prototype.fire = function () {
|
|
11
|
+
addEventListener('fetch', (event) => {
|
|
12
|
+
void event.respondWith(this.handleEvent(event));
|
|
13
|
+
});
|
|
14
|
+
};
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
2
|
import type { Context } from '../../context';
|
|
3
3
|
import type { Next } from '../../hono';
|
|
4
|
+
declare module '../../context' {
|
|
5
|
+
interface Context {
|
|
6
|
+
render: (content: string, params?: object, options?: object) => Response | Promise<Response>;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
4
9
|
export declare type MustacheOptions = {
|
|
5
10
|
root: string;
|
|
6
11
|
manifest?: object | string;
|
|
@@ -13,7 +13,7 @@ const serveStatic = (options = { root: '' }) => {
|
|
|
13
13
|
}
|
|
14
14
|
const url = new URL(c.req.url);
|
|
15
15
|
const path = (0, cloudflare_1.getKVFilePath)({
|
|
16
|
-
filename: url.pathname,
|
|
16
|
+
filename: options.path ?? url.pathname,
|
|
17
17
|
root: options.root,
|
|
18
18
|
defaultDocument: DEFAULT_DOCUMENT,
|
|
19
19
|
});
|
package/dist/utils/cloudflare.js
CHANGED
|
@@ -50,7 +50,7 @@ const getKVFilePath = (options) => {
|
|
|
50
50
|
filename = filename.concat('/' + defaultDocument);
|
|
51
51
|
}
|
|
52
52
|
// /foo.html => foo.html
|
|
53
|
-
filename = filename.replace(
|
|
53
|
+
filename = filename.replace(/^\.?\//, '');
|
|
54
54
|
// assets/ => assets
|
|
55
55
|
root = root.replace(/\/$/, '');
|
|
56
56
|
// ./assets/foo.html => assets/foo.html
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Ultrafast web framework for Cloudflare Workers.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
"test": "jest",
|
|
12
12
|
"lint": "eslint --ext js,ts src .eslintrc.js",
|
|
13
13
|
"lint:fix": "eslint --ext js,ts src .eslintrc.js --fix",
|
|
14
|
+
"denoify": "rimraf deno_dist && denoify",
|
|
14
15
|
"build": "rimraf dist && tsc --project tsconfig.build.esm.json && tsc --project tsconfig.build.json",
|
|
15
16
|
"watch": "tsc --project tsconfig.build.json -w",
|
|
16
|
-
"
|
|
17
|
+
"prerelease": "yarn denoify && yarn build",
|
|
18
|
+
"release": "np"
|
|
17
19
|
},
|
|
18
20
|
"exports": {
|
|
19
21
|
".": "./dist/index.js",
|
|
@@ -112,6 +114,9 @@
|
|
|
112
114
|
"type": "git",
|
|
113
115
|
"url": "https://github.com/honojs/hono.git"
|
|
114
116
|
},
|
|
117
|
+
"publishConfig": {
|
|
118
|
+
"registry": "https://registry.npmjs.org"
|
|
119
|
+
},
|
|
115
120
|
"homepage": "https://github.com/honojs/hono",
|
|
116
121
|
"keywords": [
|
|
117
122
|
"web",
|
|
@@ -134,6 +139,7 @@
|
|
|
134
139
|
"@typescript-eslint/eslint-plugin": "^5.21.0",
|
|
135
140
|
"@typescript-eslint/parser": "^5.21.0",
|
|
136
141
|
"crypto-js": "^4.1.1",
|
|
142
|
+
"denoify": "^0.11.1",
|
|
137
143
|
"eslint": "^8.14.0",
|
|
138
144
|
"eslint-config-prettier": "^8.5.0",
|
|
139
145
|
"eslint-define-config": "^1.4.0",
|
|
@@ -145,8 +151,9 @@
|
|
|
145
151
|
"form-data": "^4.0.0",
|
|
146
152
|
"graphql": "^16.4.0",
|
|
147
153
|
"jest": "27.5.1",
|
|
148
|
-
"jest-environment-miniflare": "^2.5.
|
|
154
|
+
"jest-environment-miniflare": "^2.5.1",
|
|
149
155
|
"mustache": "^4.2.0",
|
|
156
|
+
"np": "^7.6.2",
|
|
150
157
|
"prettier": "^2.6.2",
|
|
151
158
|
"prettier-plugin-md-nocjsp": "^1.2.0",
|
|
152
159
|
"rimraf": "^3.0.2",
|
|
@@ -156,4 +163,4 @@
|
|
|
156
163
|
"engines": {
|
|
157
164
|
"node": ">=11.0.0"
|
|
158
165
|
}
|
|
159
|
-
}
|
|
166
|
+
}
|