@ilha/router 0.8.12 → 0.9.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 +25 -22
- package/dist/codegen.d.ts +3 -0
- package/dist/index.d.ts +28 -3
- package/dist/index.js +2231 -2
- package/dist/{plugin-DdquB3Nf.js → plugin-DPGzrIVj.js} +510 -15
- package/dist/plugin.d.ts +9 -1
- package/dist/request-scope-D6_4rqMb.js +27 -0
- package/dist/request-scope.d.ts +20 -0
- package/dist/rolldown.d.ts +2 -1
- package/dist/rolldown.js +2 -2
- package/dist/rspack.d.ts +1 -0
- package/dist/rspack.js +2 -2
- package/dist/server-island-registry.d.ts +77 -0
- package/dist/server-island-registry.js +130 -0
- package/dist/server-island.d.ts +44 -0
- package/dist/server-island.js +229 -0
- package/dist/server-islands.d.ts +72 -0
- package/dist/ssr.d.ts +17 -88
- package/dist/ssr.js +136 -126
- package/dist/vite.d.ts +1 -0
- package/dist/vite.js +2 -2
- package/package.json +13 -5
- package/dist/src-BKWkRtMx.js +0 -2119
package/README.md
CHANGED
|
@@ -36,33 +36,36 @@ router()
|
|
|
36
36
|
import { router } from "@ilha/router";
|
|
37
37
|
import { homePage, aboutPage, userPage, notFound } from "./pages";
|
|
38
38
|
|
|
39
|
-
export default
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
39
|
+
export default {
|
|
40
|
+
fetch(request: Request) {
|
|
41
|
+
const html = router()
|
|
42
|
+
.route("/", homePage)
|
|
43
|
+
.route("/about", aboutPage)
|
|
44
|
+
.route("/user/:id", userPage)
|
|
45
|
+
.route("/**", notFound)
|
|
46
|
+
.render(request.url);
|
|
47
|
+
return new Response(`<!doctype html><html><body>${html}</body></html>`, {
|
|
48
|
+
headers: { "content-type": "text/html" },
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
};
|
|
51
52
|
```
|
|
52
53
|
|
|
53
54
|
### SSR + Client Hydration (recommended)
|
|
54
55
|
|
|
55
56
|
```ts
|
|
56
|
-
// routes/[...].ts —
|
|
57
|
+
// routes/[...].ts — Oxide handler (SSR/prerender)
|
|
57
58
|
import { pageRouter, registry } from "ilha:pages/server";
|
|
58
59
|
import "ilha:loaders"; // ← wire server-only loaders
|
|
59
60
|
|
|
60
|
-
export default
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
});
|
|
61
|
+
export default {
|
|
62
|
+
async fetch(request: Request) {
|
|
63
|
+
const html = await pageRouter.renderHydratable(request.url, registry);
|
|
64
|
+
return new Response(`<!doctype html><html><body>${html}</body></html>`, {
|
|
65
|
+
headers: { "content-type": "text/html" },
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
};
|
|
66
69
|
```
|
|
67
70
|
|
|
68
71
|
```ts
|
|
@@ -154,7 +157,7 @@ Returns a `RouterBuilder`.
|
|
|
154
157
|
|
|
155
158
|
#### `.route(pattern, island, loader?)`
|
|
156
159
|
|
|
157
|
-
Registers a route. Patterns
|
|
160
|
+
Registers a route. Patterns support `:param` segments and a trailing `/**:name` catch-all; static segments take priority over params, which take priority over the catch-all — regardless of registration order.
|
|
158
161
|
|
|
159
162
|
The optional `loader` is a data-fetching function that runs before the page renders. Its return value is passed as input props to the island. The loader runs **wherever the router runs**: during SSR it executes on the server; when the route was registered in the browser (a plain SPA, hash mode, `file://`), client navigations execute it locally — no server or `/__ilha/loader` endpoint needed. Routes marked via `.markLoader()` (the SSR-split pages build) still fetch from the endpoint.
|
|
160
163
|
|
|
@@ -1013,7 +1016,7 @@ The plugin exposes separate server and client virtual modules. **Always use the
|
|
|
1013
1016
|
|
|
1014
1017
|
| Module | Exports | Use for |
|
|
1015
1018
|
| ------------------- | ------------------------ | -------------------------------------- |
|
|
1016
|
-
| `ilha:pages/server` | `pageRouter`, `registry` | SSR, prerender,
|
|
1019
|
+
| `ilha:pages/server` | `pageRouter`, `registry` | SSR, prerender, server handlers |
|
|
1017
1020
|
| `ilha:pages/client` | `pageRouter`, `registry` | Browser hydration entry |
|
|
1018
1021
|
| `ilha:loaders` | — | Server-only side-effect: wires loaders |
|
|
1019
1022
|
|
|
@@ -1099,7 +1102,7 @@ Or use the one-liner: `pageRouter.hydrate(registry)`.
|
|
|
1099
1102
|
|
|
1100
1103
|
On the **server**, loaders run inside `.renderHydratable()` / `.renderResponse()`. Their return value is serialized into `data-ilha-props` on the island element so the client can rehydrate without re-fetching.
|
|
1101
1104
|
|
|
1102
|
-
On the **client**, navigations resolve loader data before mounting the next island. Routes with a loader registered in the browser — a manual `.route(path, island, loader)` or an FS-routing `clientLoad` export — run that loader locally, with no network round-trip. Routes with only a server loader (`markLoader()` / a `load` export) fetch from the `/__ilha/loader` endpoint, served automatically by the Vite plugin (dev) and the
|
|
1105
|
+
On the **client**, navigations resolve loader data before mounting the next island. Routes with a loader registered in the browser — a manual `.route(path, island, loader)` or an FS-routing `clientLoad` export — run that loader locally, with no network round-trip. Routes with only a server loader (`markLoader()` / a `load` export) fetch from the `/__ilha/loader` endpoint, served automatically by the Vite plugin (dev) and the server adapter (production).
|
|
1103
1106
|
|
|
1104
1107
|
```
|
|
1105
1108
|
server client (navigation)
|
package/dist/codegen.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/** Server pages: `foo.server.tsx` routes `/foo`, rendered through the frame protocol. */
|
|
2
|
+
export declare const SERVER_PAGE_RE: RegExp;
|
|
3
|
+
export declare function fileToPattern(pagesDir: string, file: string): string;
|
|
1
4
|
export type PagesMode = "spa" | "static";
|
|
2
5
|
export interface GenerateOptions {
|
|
3
6
|
/** Client navigation mode. Default: `spa`. */
|
package/dist/index.d.ts
CHANGED
|
@@ -71,6 +71,9 @@ export type Loader<T> = (ctx: LoaderContext) => Promise<T> | T;
|
|
|
71
71
|
* in flight, so `useRoute().params()` inside a loader reads stale params.
|
|
72
72
|
*/
|
|
73
73
|
export declare function loader<T>(fn: Loader<T>): Loader<T>;
|
|
74
|
+
export declare namespace loader {
|
|
75
|
+
var client: <T>(fn: Loader<T>) => Loader<T>;
|
|
76
|
+
}
|
|
74
77
|
/** Extract the return type of a loader. */
|
|
75
78
|
export type InferLoader<L> = L extends Loader<infer T> ? Awaited<T> : never;
|
|
76
79
|
/**
|
|
@@ -165,7 +168,7 @@ export interface RouterOptions {
|
|
|
165
168
|
export interface HydratableRenderOptions extends Partial<Omit<HydratableOptions, "name">> {
|
|
166
169
|
/**
|
|
167
170
|
* Base `<head>` data merged before loader and render-time contributions, so
|
|
168
|
-
* route-level head overrides it. Used by host entries
|
|
171
|
+
* route-level head overrides it. Used by host entries rendering routes server-side
|
|
169
172
|
* to supply app-wide title/meta/scripts.
|
|
170
173
|
*/
|
|
171
174
|
baseHead?: HeadInput;
|
|
@@ -222,7 +225,7 @@ export interface RouterBuilder {
|
|
|
222
225
|
/**
|
|
223
226
|
* Attach a loader that runs **in the browser** on client navigations,
|
|
224
227
|
* instead of fetching from the loader endpoint. Used by the FS-routing
|
|
225
|
-
* codegen for `
|
|
228
|
+
* codegen for `loader.client` exports; also available for manual routers.
|
|
226
229
|
* When a route has both, the client loader wins on client navigations and
|
|
227
230
|
* the server loader runs during SSR. No-op if the pattern was never
|
|
228
231
|
* registered via `.route()`.
|
|
@@ -259,7 +262,7 @@ export interface RouterBuilder {
|
|
|
259
262
|
renderResponse(url: string | URL, registry: Record<string, Island<any, any>>, options?: HydratableRenderOptions, request?: Request): Promise<RenderResponse>;
|
|
260
263
|
/**
|
|
261
264
|
* Run the loader chain for a given URL without rendering. Backs the
|
|
262
|
-
* `/__ilha/loader` endpoint that the host server handler
|
|
265
|
+
* `/__ilha/loader` endpoint that the host server handler
|
|
263
266
|
* serves as JSON for client-side navigation. Returns the raw loader result, a
|
|
264
267
|
* redirect sentinel, or an error sentinel.
|
|
265
268
|
*/
|
|
@@ -314,6 +317,28 @@ export declare function navigating(): boolean;
|
|
|
314
317
|
* server or when no router is mounted.
|
|
315
318
|
*/
|
|
316
319
|
export declare function invalidate(): Promise<void>;
|
|
320
|
+
/**
|
|
321
|
+
* Context seeded for server-owned island renders. Extensible: future entries
|
|
322
|
+
* (route params, app middleware values) land here without moving call sites.
|
|
323
|
+
*/
|
|
324
|
+
export interface IslandContext {
|
|
325
|
+
/**
|
|
326
|
+
* The `Request` seeding this render, when one exists — page SSR passes the
|
|
327
|
+
* incoming request; frame renders pass a synthesized POST with forwarded
|
|
328
|
+
* identity headers (`cookie`, `authorization`, …). Absent in unscoped
|
|
329
|
+
* renders (plain `toString()` in tests).
|
|
330
|
+
*/
|
|
331
|
+
request?: Request;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The context seeding the current server-island render. Always returns an
|
|
335
|
+
* object — check `.request` rather than the context itself. Never throws, so
|
|
336
|
+
* render functions stay safe under plain `toString()` calls and in tests.
|
|
337
|
+
*
|
|
338
|
+
* Only meaningful inside `.server.tsx` render functions (page SSR or frame
|
|
339
|
+
* rendering); client code never has a reason to call it.
|
|
340
|
+
*/
|
|
341
|
+
export declare function useContext(): IslandContext;
|
|
317
342
|
export declare function useRoute(): {
|
|
318
343
|
path: typeof routePath;
|
|
319
344
|
params: typeof routeParams;
|