@netrojs/vono 0.0.1 → 0.1.1
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/dist/server.js +7 -3
- package/package.json +1 -1
- package/server.ts +41 -17
- package/LICENSE +0 -21
package/dist/server.js
CHANGED
|
@@ -192,7 +192,7 @@ async function resolveComponent(comp) {
|
|
|
192
192
|
}
|
|
193
193
|
return comp;
|
|
194
194
|
}
|
|
195
|
-
async function renderPage(route, data, url, params, appLayout) {
|
|
195
|
+
async function renderPage(route, data, url, params, appLayout, dev) {
|
|
196
196
|
const layout = route.layout !== void 0 ? route.layout : appLayout;
|
|
197
197
|
const PageComp = await resolveComponent(route.page.component);
|
|
198
198
|
const routeComp = layout ? defineComponent({
|
|
@@ -211,6 +211,7 @@ async function renderPage(route, data, url, params, appLayout) {
|
|
|
211
211
|
});
|
|
212
212
|
app.use(router);
|
|
213
213
|
await router.isReady();
|
|
214
|
+
if (dev) return renderToString(app);
|
|
214
215
|
return renderToWebStream(app);
|
|
215
216
|
}
|
|
216
217
|
function buildResponseStream(headHtml, bodyStream, tailHtml) {
|
|
@@ -306,8 +307,11 @@ function createVono(config) {
|
|
|
306
307
|
assets.styles,
|
|
307
308
|
config.htmlAttrs
|
|
308
309
|
);
|
|
309
|
-
const
|
|
310
|
-
|
|
310
|
+
const body = await renderPage(route, data, pathname, params, config.layout, isDev);
|
|
311
|
+
if (isDev) {
|
|
312
|
+
return c.html(head + body + tail, 200);
|
|
313
|
+
}
|
|
314
|
+
const stream = buildResponseStream(head, body, tail);
|
|
311
315
|
return c.body(stream, 200, {
|
|
312
316
|
"Content-Type": "text/html; charset=UTF-8",
|
|
313
317
|
"Transfer-Encoding": "chunked",
|
package/package.json
CHANGED
package/server.ts
CHANGED
|
@@ -192,13 +192,37 @@ async function resolveComponent(comp: Component | ((...a: unknown[]) => unknown)
|
|
|
192
192
|
* against the correct route and never emits a spurious
|
|
193
193
|
* "[Vue Router warn]: No match found for location with path '/'" warning.
|
|
194
194
|
*/
|
|
195
|
+
/**
|
|
196
|
+
* Builds a fresh Vue SSR app + router per request and renders the page body.
|
|
197
|
+
*
|
|
198
|
+
* DEV MODE — returns a `string` via `renderToString`.
|
|
199
|
+
* `@hono/vite-dev-server` proxies requests through Vite's Connect middleware
|
|
200
|
+
* pipeline. That pipeline does not flush a `ReadableStream` — the browser
|
|
201
|
+
* hangs waiting for bytes that never arrive, then reports
|
|
202
|
+
* "localhost refused to connect" after the idle timeout fires.
|
|
203
|
+
* `renderToString` buffers the full HTML and returns it as a plain string
|
|
204
|
+
* which Hono serialises to a normal HTTP response — no streaming needed.
|
|
205
|
+
*
|
|
206
|
+
* PRODUCTION — returns a `ReadableStream<Uint8Array>` via `renderToWebStream`.
|
|
207
|
+
* Lower TTFB: the browser receives `<head>` (CSS links, preload hints,
|
|
208
|
+
* critical scripts) while Vue is still rendering the `<body>`.
|
|
209
|
+
*
|
|
210
|
+
* Vue Router warning fix:
|
|
211
|
+
* `createMemoryHistory()` starts at '/'. The router performs an internal
|
|
212
|
+
* startup navigation to that initial location before any routes are matched.
|
|
213
|
+
* If the only registered route is e.g. '/about', Vue Router emits:
|
|
214
|
+
* "[Vue Router warn]: No match found for location with path '/'"
|
|
215
|
+
* Fix: call `memHistory.replace(url)` BEFORE constructing the router so its
|
|
216
|
+
* startup navigation always resolves against the correct, matched route.
|
|
217
|
+
*/
|
|
195
218
|
async function renderPage(
|
|
196
219
|
route: ResolvedRoute,
|
|
197
220
|
data: object,
|
|
198
221
|
url: string,
|
|
199
222
|
params: Record<string, string>,
|
|
200
223
|
appLayout: LayoutDef | undefined,
|
|
201
|
-
|
|
224
|
+
dev: boolean,
|
|
225
|
+
): Promise<ReadableStream<Uint8Array> | string> {
|
|
202
226
|
const layout = route.layout !== undefined ? route.layout : appLayout
|
|
203
227
|
|
|
204
228
|
// Resolve async component loaders — critical for SSR correctness
|
|
@@ -217,16 +241,8 @@ async function renderPage(
|
|
|
217
241
|
const app = createSSRApp({ render: () => h(RouterView) })
|
|
218
242
|
app.provide(DATA_KEY, data)
|
|
219
243
|
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
// is constructed it performs an internal navigation to that initial location.
|
|
223
|
-
// If the only registered route is e.g. '/about', no match is found and
|
|
224
|
-
// Vue Router emits a warning even though the subsequent router.push('/about')
|
|
225
|
-
// succeeds perfectly.
|
|
226
|
-
//
|
|
227
|
-
// Fix: call history.replace(url) BEFORE constructing the router. The router
|
|
228
|
-
// then sees the correct initial location and its startup navigation succeeds
|
|
229
|
-
// without warnings. No separate router.push() is required.
|
|
244
|
+
// Initialise history at the request URL before creating the router so its
|
|
245
|
+
// startup navigation resolves immediately without a "[Vue Router warn]".
|
|
230
246
|
const memHistory = createMemoryHistory()
|
|
231
247
|
memHistory.replace(url)
|
|
232
248
|
|
|
@@ -236,11 +252,11 @@ async function renderPage(
|
|
|
236
252
|
})
|
|
237
253
|
app.use(router)
|
|
238
254
|
|
|
239
|
-
// router.isReady() resolves once the initial navigation (to `url`) completes.
|
|
240
255
|
await router.isReady()
|
|
241
256
|
|
|
242
|
-
//
|
|
243
|
-
//
|
|
257
|
+
// Dev: buffered string — works correctly inside @hono/vite-dev-server.
|
|
258
|
+
// Prod: streaming — flushes <head> to the browser before <body> is ready.
|
|
259
|
+
if (dev) return renderToString(app)
|
|
244
260
|
return renderToWebStream(app)
|
|
245
261
|
}
|
|
246
262
|
|
|
@@ -389,10 +405,18 @@ export function createVono(config: VonoOptions): VonoApp {
|
|
|
389
405
|
config.htmlAttrs,
|
|
390
406
|
)
|
|
391
407
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
408
|
+
const body = await renderPage(route, data, pathname, params, config.layout, isDev)
|
|
409
|
+
|
|
410
|
+
// Dev: body is a plain string — return a normal buffered HTML response.
|
|
411
|
+
// @hono/vite-dev-server cannot flush a ReadableStream through Vite's
|
|
412
|
+
// Connect pipeline; using c.html() avoids the hanging-connection issue.
|
|
413
|
+
if (isDev) {
|
|
414
|
+
return c.html(head + (body as string) + tail, 200)
|
|
415
|
+
}
|
|
395
416
|
|
|
417
|
+
// Production: body is a ReadableStream — stream head + body + tail for
|
|
418
|
+
// the lowest possible TTFB.
|
|
419
|
+
const stream = buildResponseStream(head, body as ReadableStream<Uint8Array>, tail)
|
|
396
420
|
return c.body(stream, 200, {
|
|
397
421
|
'Content-Type': 'text/html; charset=UTF-8',
|
|
398
422
|
'Transfer-Encoding': 'chunked',
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Netro Solutions
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|