Skip to content

Commit 37a5bd7

Browse files
committed
Use Bun for tests
1 parent 72d6e1b commit 37a5bd7

15 files changed

+234
-235
lines changed

.npmignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@
55
.gitignore
66
.npmignore
77
tsconfig.json
8-
prettier.config.mjs
9-
vitest.config.ts
8+
prettier.config.mjs

README.md

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
# Remix + Hono
1+
# Remix/React Router + Hono
22

3-
> [Remix](https://remix.run) is a web framework for building web applications,
4-
> which can run on the Edge.
3+
> [React Router](https://remix.run) is a web framework for building web
4+
> applications, which can run on the Edge.
55
66
> [Hono](https://hono.dev) is a small and ultrafast web framework for the Edges.
77
8-
This adapter allows you to use Hono with Remix, so you can use the best of each
9-
one.
8+
This adapter allows you to use Hono with React Router, so you can use the best
9+
of each one.
1010

11-
Let Hono power your HTTP server and its middlewares, then use Remix to build
12-
your web application.
11+
Let Hono power your HTTP server and its middlewares, then use React Router to
12+
build your web application.
1313

1414
## Installation
1515

@@ -22,26 +22,26 @@ npm add remix-hono
2222
The following packages are optional dependencies, you will need to install them
2323
depending on what features from remix-hono you're using.
2424

25-
- `@remix-run/cloudflare` if you're using Cloudflare integration.
25+
- `@react-router/cloudflare` if you're using Cloudflare integration.
2626
- `i18next` and `remix-i18next` if you're using the i18n middleware.
2727
- `zod` if you're using `typedEnv`.
2828

29-
> [!NOTE]
30-
> You don't really need to install them if you don't use them, but you
29+
> [!NOTE] You don't really need to install them if you don't use them, but you
3130
> will need to install them yourself (they don't come not automatically) if you
3231
> use the features that depends on those packages.
3332
3433
## Usage
3534

36-
Create your Hono + Remix server:
35+
Create your Hono + React Routers server:
3736

3837
```ts
39-
import { logDevReady } from "@remix-run/cloudflare";
40-
import * as build from "@remix-run/dev/server-build";
38+
import { logDevReady } from "@react-router/cloudflare";
4139
import { Hono } from "hono";
4240
// You can also use it with other runtimes
4341
import { handle } from "hono/cloudflare-pages";
44-
import { remix } from "remix-hono/handler";
42+
import { reactRouter } from "remix-hono/handler";
43+
44+
import build from "./build/server";
4545

4646
if (process.env.NODE_ENV === "development") logDevReady(build);
4747

@@ -55,10 +55,10 @@ type ContextEnv = { Bindings: Bindings; Variables: Variables };
5555

5656
const server = new Hono<ContextEnv>();
5757

58-
// Add the Remix middleware to your Hono server
58+
// Add the React Router middleware to your Hono server
5959
server.use(
6060
"*",
61-
remix({
61+
reactRouter({
6262
build,
6363
mode: process.env.NODE_ENV as "development" | "production",
6464
// getLoadContext is optional, the default function is the same as here
@@ -79,9 +79,9 @@ import { basicAuth } from "hono/basic-auth";
7979

8080
server.use(
8181
"*",
82-
basicAuth({ username: "hono", password: "remix" }),
83-
// Ensure Remix request handler is the last one
84-
remix(options),
82+
basicAuth({ username: "hono", password: "react-router" }),
83+
// Ensure React Router request handler is the last one
84+
reactRouter(options),
8585
);
8686
```
8787

@@ -90,20 +90,18 @@ great of preview applications.
9090

9191
## Session Management
9292

93-
Additionally to the `remix` Hono middleware, there are other three middlewares
94-
to work with Remix sessions.
93+
Additionally to the `reactRouter` Hono middleware, there are other three
94+
middlewares to work with React Router sessions.
9595

96-
Because Remix sessions typically use a secret coming from the environment you
97-
will need access to Hono `c.env` to use them. If you're using the Worker KV
96+
Because React Router sessions typically use a secret coming from the environment
97+
you will need access to Hono `c.env` to use them. If you're using the Worker KV
9898
session storage you will also need to pass the KV binding to the middleware.
9999

100100
You can use the different middlewares included in this package to do that:
101101

102102
```ts
103103
import { session } from "remix-hono/session";
104-
// Install the `@remix-run/*` package for your server adapter to grab the
105-
// factory functions for session storage
106-
import { createWorkerKVSessionStorage } from "@remix-run/cloudflare";
104+
import { createWorkerKVSessionStorage } from "@react-router/cloudflare";
107105

108106
server.use(
109107
"*",
@@ -123,7 +121,7 @@ server.use(
123121
);
124122
```
125123

126-
Now, setup the Remix middleware after your session middleware and use the
124+
Now, setup the React Router middleware after your session middleware and use the
127125
helpers `getSessionStorage` and `getSession` to access the SessionStorage and
128126
Session objects.
129127

@@ -136,7 +134,7 @@ import { getSessionStorage, getSession } from "remix-hono/session";
136134

137135
server.use(
138136
"*",
139-
remix<ContextEnv>({
137+
reactRouter<ContextEnv>({
140138
build,
141139
mode: process.env.NODE_ENV as "development" | "production",
142140
// getLoadContext is optional, the default function is the same as here
@@ -205,32 +203,33 @@ If you're using Remix Hono with Cloudflare, you will need to serve your static
205203
from the public folder (except for `public/build`). The `staticAssets`
206204
middleware serves this purpose.
207205

208-
First install `@remix-run/cloudflare` if you haven't installed it yet.
206+
First install `@react-router/cloudflare` if you haven't installed it yet.
209207

210208
```sh
211-
npm add @remix-run/cloudflare
209+
npm add @react-router/cloudflare
212210
```
213211

214212
Then use the middleware in your server.
215213

216214
```ts
217215
import { staticAssets } from "remix-hono/cloudflare";
218-
import { remix } from "remix-hono/handler";
216+
import { reactRouter } from "remix-hono/handler";
219217

220218
server.use(
221219
"*",
222220
staticAssets(),
223-
// Add Remix request handler as the last middleware
224-
remix(options),
221+
// Add React Router request handler as the last middleware
222+
reactRouter(options),
225223
);
226224
```
227225

228226
## i18next integration
229227

230228
If you're using [remix-i18next](https://github.com/sergiodxa/remix-i18next) to
231-
support i18n in your Remix app, the `i18next` middleware let's you setup it for
232-
your Remix app as a middleware that you can later use in your `getLoadContext`
233-
function to pass the `locale` and `t` functions to your loaders and actions.
229+
support i18n in your React Router app, the `i18next` middleware let's you setup
230+
it for your React Router app as a middleware that you can later use in your
231+
`getLoadContext` function to pass the `locale` and `t` functions to your loaders
232+
and actions.
234233

235234
First install `i18next` and `remix-i18next` if you haven't already.
236235

@@ -253,7 +252,7 @@ functions using the helpers `i18next.getLocale` and `i18next.getFixedT`.
253252
```ts
254253
server.use(
255254
"*",
256-
remix({
255+
reactRouter({
257256
build,
258257
mode: process.env.NODE_ENV as "development" | "production",
259258
// getLoadContext is optional, the default function is the same as here

bun.lockb

-18.8 KB
Binary file not shown.

bunfig.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[test]
2+
preload = "./test/setup.ts"

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"keywords": [
88
"remix",
99
"remix-run",
10+
"react-router",
1011
"hono",
1112
"cloudflare",
1213
"cloudflare-pages"
@@ -62,10 +63,10 @@
6263
"url": "https://github.com/sponsors/sergiodxa"
6364
},
6465
"scripts": {
65-
"build": "tsc --project tsconfig.json --outDir ./build",
66-
"typecheck": "tsc --project tsconfig.json --noEmit",
67-
"lint": "eslint --ext .ts,.tsx src/ test/",
68-
"test": "vitest",
66+
"build": "tsc",
67+
"typecheck": "tsc --noEmit",
68+
"quality": "biome check .",
69+
"quality:fix": "biome check . --write --unsafe",
6970
"exports": "bun run ./scripts/exports.ts"
7071
},
7172
"dependencies": {
@@ -80,6 +81,9 @@
8081
"zod": "^3.0.0"
8182
},
8283
"peerDependenciesMeta": {
84+
"react-router": {
85+
"optional": true
86+
},
8387
"@react-router/cloudflare": {
8488
"optional": true
8589
},
@@ -95,14 +99,12 @@
9599
},
96100
"devDependencies": {
97101
"@cloudflare/workers-types": "^4.20241112.0",
98-
"@edge-runtime/vm": "^4.0.4",
99102
"@react-router/cloudflare": "^7.0.1",
100-
"@react-router/node": "^7.0.1",
101103
"@total-typescript/tsconfig": "^1.0.4",
104+
"@types/bun": "^1.1.14",
102105
"@types/node": "^20.11.28",
103106
"@typescript-eslint/eslint-plugin": "^7.2.0",
104107
"@typescript-eslint/parser": "^7.2.0",
105-
"@vitest/coverage-v8": "^2.1.5",
106108
"eslint": "^8.57.0",
107109
"eslint-config-prettier": "^9.1.0",
108110
"eslint-import-resolver-typescript": "^3.6.1",
@@ -118,7 +120,6 @@
118120
"typescript": "^5.7.2",
119121
"vite": "^5.4.11",
120122
"vite-tsconfig-paths": "^5.1.3",
121-
"vitest": "^2.1.5",
122123
"zod": "^3.22.4"
123124
}
124125
}

src/cloudflare.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
import type {
2+
Fetcher,
3+
RequestInit,
4+
KVNamespace,
5+
} from "@cloudflare/workers-types";
16
import type { Context } from "hono";
27

38
import { createWorkersKVSessionStorage } from "@react-router/cloudflare";
49
import { createMiddleware } from "hono/factory";
510
import { cacheHeader } from "pretty-cache-header";
611
import {
7-
CookieOptions,
8-
SessionData,
12+
type CookieOptions,
13+
type SessionData,
914
createCookieSessionStorage,
1015
} from "react-router";
1116

@@ -26,7 +31,10 @@ export function staticAssets(options: StaticAssetsOptions = {}) {
2631
c.req.raw.headers.delete("if-none-match");
2732

2833
try {
29-
response = await binding.fetch(c.req.url, c.req.raw.clone());
34+
response = (await binding.fetch(
35+
c.req.url,
36+
c.req.raw.clone() as unknown as RequestInit,
37+
)) as unknown as globalThis.Response;
3038

3139
// If the request failed, we just call the next middleware
3240
if (response.status >= 400) return await next();

src/handler.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import type { AppLoadContext, ServerBuild } from "react-router";
44
import { createMiddleware } from "hono/factory";
55
import { createRequestHandler } from "react-router";
66

7-
export interface RemixMiddlewareOptions {
7+
export interface ReactRouterMiddlewareOptions {
88
build: ServerBuild;
99
mode?: "development" | "production";
1010
getLoadContext?(c: Context): Promise<AppLoadContext> | AppLoadContext;
1111
}
1212

13-
export function remix({
13+
export function reactRouter({
1414
mode,
1515
build,
1616
getLoadContext = (c) => c.env as unknown as AppLoadContext,
17-
}: RemixMiddlewareOptions) {
17+
}: ReactRouterMiddlewareOptions) {
1818
return createMiddleware(async (c) => {
1919
let requestHandler = createRequestHandler(build, mode);
2020
let loadContext = getLoadContext(c);
@@ -24,5 +24,3 @@ export function remix({
2424
);
2525
});
2626
}
27-
28-
export { createRequestHandler } from "react-router";

src/session.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ export function session<Data = SessionData, FlashData = Data>(options: {
2222
// If autoCommit is disabled, we just create the SessionStorage and make it
2323
// available with c.get(sessionStorageSymbol), then call next() and
2424
// return.
25-
if (!options.autoCommit) {
26-
return await next();
27-
}
25+
if (!options.autoCommit) return await next();
2826

2927
// If autoCommit is enabled, we get the Session from the request.
3028
let session = await sessionStorage.getSession(

0 commit comments

Comments
 (0)