@canonical/react-ssr 0.27.1-experimental.0 → 0.28.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 +74 -27
- package/dist/esm/bin/serve-bun.js +77 -0
- package/dist/esm/bin/serve-bun.js.map +1 -0
- package/dist/esm/bin/serve-express.js +19 -36
- package/dist/esm/bin/serve-express.js.map +1 -1
- package/dist/esm/lib/adapter/index.js +1 -1
- package/dist/esm/lib/adapter/index.js.map +1 -1
- package/dist/esm/lib/adapter/mime.js +7 -0
- package/dist/esm/lib/adapter/mime.js.map +1 -1
- package/dist/esm/lib/renderer/JSXRenderer.js +2 -0
- package/dist/esm/lib/renderer/JSXRenderer.js.map +1 -1
- package/dist/esm/lib/renderer/SitemapRenderer.js +2 -0
- package/dist/esm/lib/renderer/SitemapRenderer.js.map +1 -1
- package/dist/esm/lib/server/StaticMount.js +2 -0
- package/dist/esm/lib/server/StaticMount.js.map +1 -0
- package/dist/esm/lib/server/getRequestUrl.js +41 -0
- package/dist/esm/lib/server/getRequestUrl.js.map +1 -0
- package/dist/esm/lib/server/index.js +6 -0
- package/dist/esm/lib/server/index.js.map +1 -1
- package/dist/esm/lib/server/matchStaticRoute.js +14 -0
- package/dist/esm/lib/server/matchStaticRoute.js.map +1 -0
- package/dist/esm/lib/server/parseStaticPair.js +20 -0
- package/dist/esm/lib/server/parseStaticPair.js.map +1 -0
- package/dist/esm/lib/server/resolvePort.js +29 -0
- package/dist/esm/lib/server/resolvePort.js.map +1 -0
- package/dist/esm/lib/server/resolveStaticFile.js +61 -0
- package/dist/esm/lib/server/resolveStaticFile.js.map +1 -0
- package/dist/esm/lib/server/serveStream.js +1 -1
- package/dist/esm/lib/server/serveStream.js.map +1 -1
- package/dist/esm/lib/server/viteFetchMiddleware.js +152 -0
- package/dist/esm/lib/server/viteFetchMiddleware.js.map +1 -0
- package/dist/types/bin/serve-bun.d.ts +25 -0
- package/dist/types/bin/serve-bun.d.ts.map +1 -0
- package/dist/types/bin/serve-express.d.ts +6 -3
- package/dist/types/bin/serve-express.d.ts.map +1 -1
- package/dist/types/lib/adapter/index.d.ts +1 -1
- package/dist/types/lib/adapter/index.d.ts.map +1 -1
- package/dist/types/lib/adapter/mime.d.ts +7 -0
- package/dist/types/lib/adapter/mime.d.ts.map +1 -1
- package/dist/types/lib/adapter/types.d.ts +8 -10
- package/dist/types/lib/adapter/types.d.ts.map +1 -1
- package/dist/types/lib/renderer/JSXRenderer.d.ts +2 -0
- package/dist/types/lib/renderer/JSXRenderer.d.ts.map +1 -1
- package/dist/types/lib/renderer/SitemapRenderer.d.ts +2 -0
- package/dist/types/lib/renderer/SitemapRenderer.d.ts.map +1 -1
- package/dist/types/lib/server/StaticMount.d.ts +11 -0
- package/dist/types/lib/server/StaticMount.d.ts.map +1 -0
- package/dist/types/lib/server/getRequestUrl.d.ts +29 -0
- package/dist/types/lib/server/getRequestUrl.d.ts.map +1 -0
- package/dist/types/lib/server/index.d.ts +7 -0
- package/dist/types/lib/server/index.d.ts.map +1 -1
- package/dist/types/lib/server/matchStaticRoute.d.ts +12 -0
- package/dist/types/lib/server/matchStaticRoute.d.ts.map +1 -0
- package/dist/types/lib/server/parseStaticPair.d.ts +12 -0
- package/dist/types/lib/server/parseStaticPair.d.ts.map +1 -0
- package/dist/types/lib/server/resolvePort.d.ts +20 -0
- package/dist/types/lib/server/resolvePort.d.ts.map +1 -0
- package/dist/types/lib/server/resolveStaticFile.d.ts +20 -0
- package/dist/types/lib/server/resolveStaticFile.d.ts.map +1 -0
- package/dist/types/lib/server/serveStream.d.ts +1 -0
- package/dist/types/lib/server/serveStream.d.ts.map +1 -1
- package/dist/types/lib/server/viteFetchMiddleware.d.ts +81 -0
- package/dist/types/lib/server/viteFetchMiddleware.d.ts.map +1 -0
- package/package.json +11 -7
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal structural type for the parts of Vite's dev server this helper uses.
|
|
4
|
+
*
|
|
5
|
+
* `vite` is an optional peer dependency of this package (it is only needed by
|
|
6
|
+
* consumers running a Vite-backed dev server). Typing structurally avoids a
|
|
7
|
+
* hard dependency on Vite's types while still describing the contract: a
|
|
8
|
+
* connect-style middleware stack `(req, res, next) => void`.
|
|
9
|
+
*/
|
|
10
|
+
export interface ViteMiddlewareServer {
|
|
11
|
+
middlewares: (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Bridge Vite's connect-style middleware into a `fetch`-style handler.
|
|
15
|
+
*
|
|
16
|
+
* Runtime SSR dev servers built on `Bun.serve` (or any Web `fetch` server)
|
|
17
|
+
* cannot mount Vite's `(req, res, next)` middleware directly: that stack
|
|
18
|
+
* expects Node's `http.IncomingMessage` / `ServerResponse`, while `fetch`
|
|
19
|
+
* deals in Web `Request` / `Response`. Without delegating to Vite, every
|
|
20
|
+
* request — including `/@vite/client`, `/src/**`, `/@id/**`, `/@fs/**`,
|
|
21
|
+
* `/@react-refresh`, and `/node_modules/.vite/**` — would have to be
|
|
22
|
+
* server-rendered, so client modules and HMR assets would be returned as the
|
|
23
|
+
* SSR HTML page with the wrong `Content-Type` (browsers then block them as
|
|
24
|
+
* modules and the page never hydrates).
|
|
25
|
+
*
|
|
26
|
+
* This helper adapts a Web `Request` into a Node `req`/`res` pair, runs Vite's
|
|
27
|
+
* middleware against it, and returns a Web `Response` if the middleware handled
|
|
28
|
+
* the request — or `null` if the stack called `next()` (a page route the
|
|
29
|
+
* caller should server-render).
|
|
30
|
+
*
|
|
31
|
+
* The bridge is **runtime-agnostic**: it depends only on `node:http` /
|
|
32
|
+
* `node:net` and Web globals (`Request`, `Response`), so it works under Bun,
|
|
33
|
+
* Node's own `fetch` servers, Deno, and Workers — not just Bun. The `vite`
|
|
34
|
+
* instance is injected, not imported, keeping this module free of a runtime
|
|
35
|
+
* Vite dependency.
|
|
36
|
+
*
|
|
37
|
+
* The response body is **buffered**: chunks written by the middleware are
|
|
38
|
+
* collected and the `Response` resolves on `end`, with `status` and `headers`
|
|
39
|
+
* read from the (by-then-final) `ServerResponse`. This is correct and robust
|
|
40
|
+
* for dev assets — transformed JS/CSS modules and source maps, which are small
|
|
41
|
+
* and already in memory when Vite writes them. Streaming would buy near-zero
|
|
42
|
+
* latency here (SSR render streaming goes through the renderer's
|
|
43
|
+
* `renderToReadableStream`, never this bridge) while introducing header-timing
|
|
44
|
+
* and backpressure hazards, so it is deliberately avoided.
|
|
45
|
+
*
|
|
46
|
+
* Headers set via `res.writeHead(status, headers)` are captured in addition to
|
|
47
|
+
* `res.getHeaders()` (Vite's static-file middleware sets `Content-Type` etc.
|
|
48
|
+
* that way for non-JS assets), and multi-value headers such as `set-cookie` are
|
|
49
|
+
* preserved as separate entries rather than comma-folded.
|
|
50
|
+
*
|
|
51
|
+
* Only `GET`/`HEAD` requests are bridged. A bare `IncomingMessage` carries no
|
|
52
|
+
* request body, so any middleware that reads one would hang; requests with a
|
|
53
|
+
* body (and other methods) return `null` so the caller handles them. This
|
|
54
|
+
* matches Vite's asset/module/HMR surface, which is entirely `GET`/`HEAD`.
|
|
55
|
+
*
|
|
56
|
+
* @param vite - A Vite dev server created with `middlewareMode: true`.
|
|
57
|
+
* @returns A function mapping a Web `Request` to a `Response` (Vite handled it)
|
|
58
|
+
* or `null` (a page route, a non-`GET`/`HEAD` request — pass through to SSR).
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* import { createServer as createViteServer } from "vite";
|
|
63
|
+
* import { viteFetchMiddleware } from "@canonical/react-ssr/server";
|
|
64
|
+
*
|
|
65
|
+
* const vite = await createViteServer({
|
|
66
|
+
* server: { middlewareMode: true },
|
|
67
|
+
* appType: "custom",
|
|
68
|
+
* });
|
|
69
|
+
* const handleAsset = viteFetchMiddleware(vite);
|
|
70
|
+
*
|
|
71
|
+
* Bun.serve({
|
|
72
|
+
* async fetch(req) {
|
|
73
|
+
* const asset = await handleAsset(req);
|
|
74
|
+
* if (asset) return asset; // /@vite/client, /src/**, CSS, HMR …
|
|
75
|
+
* return ssrRender(req); // page route
|
|
76
|
+
* },
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function viteFetchMiddleware(vite: ViteMiddlewareServer): (request: Request) => Promise<Response | null>;
|
|
81
|
+
//# sourceMappingURL=viteFetchMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viteFetchMiddleware.d.ts","sourceRoot":"","sources":["../../../../src/lib/server/viteFetchMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG5D;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,CACX,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,KAC1B,IAAI,CAAC;CACX;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,oBAAoB,GACzB,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAsGhD"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonical/react-ssr",
|
|
3
3
|
"description": "TBD",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.28.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
7
7
|
"types": "dist/types/index.d.ts",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@biomejs/biome": "2.4.9",
|
|
73
|
-
"@canonical/biome-config": "^0.
|
|
74
|
-
"@canonical/typescript-config-react": "^0.
|
|
75
|
-
"@canonical/webarchitect": "^0.
|
|
73
|
+
"@canonical/biome-config": "^0.28.0",
|
|
74
|
+
"@canonical/typescript-config-react": "^0.28.0",
|
|
75
|
+
"@canonical/webarchitect": "^0.28.0",
|
|
76
76
|
"@types/express": "^5.0.6",
|
|
77
77
|
"@types/node": "^24.12.0",
|
|
78
78
|
"@types/react": "^19.2.14",
|
|
@@ -82,18 +82,22 @@
|
|
|
82
82
|
"vitest": "^4.0.18"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
|
-
"@canonical/utils": "^0.
|
|
85
|
+
"@canonical/utils": "^0.28.0",
|
|
86
86
|
"htmlparser2": "^10.1.0",
|
|
87
87
|
"react": "^19.2.4",
|
|
88
88
|
"react-dom": "^19.2.4"
|
|
89
89
|
},
|
|
90
90
|
"peerDependencies": {
|
|
91
|
-
"express": "^5.2.1"
|
|
91
|
+
"express": "^5.2.1",
|
|
92
|
+
"vite": "^8.0.0"
|
|
92
93
|
},
|
|
93
94
|
"peerDependenciesMeta": {
|
|
94
95
|
"express": {
|
|
95
96
|
"optional": true
|
|
97
|
+
},
|
|
98
|
+
"vite": {
|
|
99
|
+
"optional": true
|
|
96
100
|
}
|
|
97
101
|
},
|
|
98
|
-
"gitHead": "
|
|
102
|
+
"gitHead": "8297d72122bcba903f7e8833cb23ccbaa164ed56"
|
|
99
103
|
}
|