@ilha/router 0.4.2 → 0.5.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 +28 -14
- package/dist/{index-DSE6uoR1.d.ts → index-DZA_1KrG.d.ts} +39 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin-BizQQLsn.d.ts +28 -0
- package/dist/{plugin-Bhbl9aqc.js → plugin-C-TVH3XD.js} +37 -9
- package/dist/rolldown.d.ts +2 -2
- package/dist/rolldown.js +2 -2
- package/dist/rspack.d.ts +2 -2
- package/dist/rspack.js +2 -2
- package/dist/{src-DX07qe2S.js → src-BP38YTMC.js} +40 -9
- package/dist/vite.d.ts +2 -2
- package/dist/vite.js +2 -2
- package/package.json +1 -1
- package/dist/plugin-Diq1AxSa.d.ts +0 -21
package/README.md
CHANGED
|
@@ -300,7 +300,7 @@ pageRouter.mount("#app", { hydrate: true, registry });
|
|
|
300
300
|
|
|
301
301
|
#### `.hydrate(registry, options?)` — browser only
|
|
302
302
|
|
|
303
|
-
Convenience method that combines `.prime()`, `ilha.mount()`, and `.mount()` into a single call. **This is the recommended client entry point.**
|
|
303
|
+
Convenience method that combines `.prime()`, `ilha.mount()`, and `.mount()` into a single call. **This is the recommended client entry point for SPA apps.**
|
|
304
304
|
|
|
305
305
|
```ts
|
|
306
306
|
pageRouter.hydrate(registry);
|
|
@@ -318,6 +318,23 @@ Returns an `unmount` function that tears down all listeners and hydrated islands
|
|
|
318
318
|
|
|
319
319
|
---
|
|
320
320
|
|
|
321
|
+
#### `.hydrateStatic(registry, options?)` — browser only
|
|
322
|
+
|
|
323
|
+
The lightest client entry point. Calls `prime()` then `ilha.mount()` — no route view is mounted, no navigation handler is installed, and no route graph is touched. Use this in `static` mode where each page is a self-contained pre-rendered HTML file.
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
pageRouter.hydrateStatic(registry);
|
|
327
|
+
|
|
328
|
+
// With options:
|
|
329
|
+
pageRouter.hydrateStatic(registry, {
|
|
330
|
+
root: document.getElementById("app"), // defaults to document.body
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Internal `<a href>` links navigate via normal browser page loads. Only interactive islands in the current page are activated.
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
321
338
|
#### `.attachLoader(pattern, loader)` — runtime
|
|
322
339
|
|
|
323
340
|
Attaches or replaces a loader on an already-registered route pattern. No-op if the pattern was never registered via `.route()`. Used by the `ilha:loaders` virtual module to wire server-only loaders onto the client-safe `pageRouter` at SSR time.
|
|
@@ -658,18 +675,21 @@ interface NavigateOptions {
|
|
|
658
675
|
interface MountOptions {
|
|
659
676
|
hydrate?: boolean;
|
|
660
677
|
registry?: Record<string, Island>;
|
|
678
|
+
interceptLinks?: boolean; // default: true
|
|
661
679
|
}
|
|
662
680
|
|
|
663
681
|
interface HydrateOptions {
|
|
664
682
|
root?: Element;
|
|
665
683
|
target?: string | Element;
|
|
684
|
+
interceptLinks?: boolean; // default: true
|
|
666
685
|
}
|
|
667
686
|
|
|
668
687
|
type HistoryMode = "history" | "hash";
|
|
669
|
-
type RouterMode = "spa" | "
|
|
688
|
+
type RouterMode = "spa" | "static";
|
|
670
689
|
|
|
671
690
|
interface RouterOptions {
|
|
672
|
-
mode?: RouterMode; // default: "spa"
|
|
691
|
+
mode?: RouterMode; // "spa" | "static", default: "spa"
|
|
692
|
+
interceptLinks?: boolean; // default: true — only meaningful in spa mode
|
|
673
693
|
}
|
|
674
694
|
|
|
675
695
|
// Helper — returns fn as-is with LayoutHandler type enforced
|
|
@@ -932,20 +952,14 @@ pageRouter.hydrate(registry);
|
|
|
932
952
|
pages({
|
|
933
953
|
dir: "src/pages", // pages directory (default: "src/pages")
|
|
934
954
|
generated: ".ilha/routes.ts", // generated file output (default: ".ilha/routes.ts")
|
|
935
|
-
mode: "spa", // "spa" | "
|
|
955
|
+
mode: "spa", // "spa" | "static" (default: "spa")
|
|
956
|
+
interceptLinks: true, // only meaningful in spa mode (default: true)
|
|
936
957
|
});
|
|
937
958
|
```
|
|
938
959
|
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
// vite.config.ts
|
|
943
|
-
import { pages } from "@ilha/router/vite";
|
|
944
|
-
|
|
945
|
-
export default defineConfig({
|
|
946
|
-
plugins: [pages({ mode: "mpa" })],
|
|
947
|
-
});
|
|
948
|
-
```
|
|
960
|
+
- **`mode: "spa"`** — full client route graph, SSR/hydration, and client-side navigation.
|
|
961
|
+
- **`mode: "spa", interceptLinks: false`** — full route graph and SSR/hydration, but internal links perform full document navigations.
|
|
962
|
+
- **`mode: "static"`** — island registry only; no route graph bundled. Each pre-rendered page hydrates its own islands via `pageRouter.hydrateStatic(registry)`.
|
|
949
963
|
|
|
950
964
|
The plugin regenerates the routes file only when content actually changes — avoiding unnecessary HMR invalidations. Structural changes (file add/remove, `+layout.ts`/`+error.ts` edits, or changes to loader exports) trigger full HMR reloads.
|
|
951
965
|
|
|
@@ -24,6 +24,8 @@ interface RouteRecord {
|
|
|
24
24
|
island: Island<any, any>;
|
|
25
25
|
/** Merged loader chain (layouts outer→inner, then page) — `undefined` if no loaders. */
|
|
26
26
|
loader?: Loader<any>;
|
|
27
|
+
/** True when the route has a server-side loader, even if the client only has a marker. */
|
|
28
|
+
hasLoader?: boolean;
|
|
27
29
|
}
|
|
28
30
|
interface RouteSnapshot {
|
|
29
31
|
path: string;
|
|
@@ -90,24 +92,43 @@ declare function defineLayout(layout: LayoutHandler): LayoutHandler;
|
|
|
90
92
|
interface NavigateOptions {
|
|
91
93
|
replace?: boolean;
|
|
92
94
|
}
|
|
93
|
-
type RouterMode = "spa" | "
|
|
95
|
+
type RouterMode = "spa" | "static";
|
|
94
96
|
interface RouterOptions {
|
|
95
97
|
/**
|
|
96
|
-
* Client navigation mode.
|
|
97
|
-
*
|
|
98
|
-
*
|
|
98
|
+
* Client navigation mode.
|
|
99
|
+
* - `spa` — full route graph, SSR/hydration, client-side navigation.
|
|
100
|
+
* - `static` — no route graph bundled; hydrate islands on the current
|
|
101
|
+
* pre-rendered page only.
|
|
99
102
|
* Default: `spa`.
|
|
100
103
|
*/
|
|
101
104
|
mode?: RouterMode;
|
|
105
|
+
/**
|
|
106
|
+
* When `true` (default), internal `<a>` clicks are intercepted and handled
|
|
107
|
+
* by the client router. Set to `false` for MPA-style behavior where links
|
|
108
|
+
* perform full document navigations.
|
|
109
|
+
* Only meaningful in `spa` mode; ignored in `static` mode.
|
|
110
|
+
* Default: `true`.
|
|
111
|
+
*/
|
|
112
|
+
interceptLinks?: boolean;
|
|
102
113
|
}
|
|
103
114
|
interface HydratableRenderOptions extends Partial<Omit<HydratableOptions, "name">> {}
|
|
104
115
|
interface HydrateOptions {
|
|
105
116
|
root?: Element;
|
|
106
117
|
target?: string | Element;
|
|
118
|
+
/**
|
|
119
|
+
* When `true` (default), internal `<a>` clicks are intercepted for
|
|
120
|
+
* client-side navigation. Set to `false` for MPA-style full-page navigations.
|
|
121
|
+
*/
|
|
122
|
+
interceptLinks?: boolean;
|
|
107
123
|
}
|
|
108
124
|
interface MountOptions {
|
|
109
125
|
hydrate?: boolean;
|
|
110
126
|
registry?: Record<string, Island<any, any>>;
|
|
127
|
+
/**
|
|
128
|
+
* When `true` (default), internal `<a>` clicks are intercepted for
|
|
129
|
+
* client-side navigation. Set to `false` for MPA-style full-page navigations.
|
|
130
|
+
*/
|
|
131
|
+
interceptLinks?: boolean;
|
|
111
132
|
}
|
|
112
133
|
/** Response envelope returned by `renderResponse` — lets the host app handle redirects. */
|
|
113
134
|
type RenderResponse = {
|
|
@@ -138,6 +159,12 @@ interface RouterBuilder {
|
|
|
138
159
|
* was never registered via `.route()`.
|
|
139
160
|
*/
|
|
140
161
|
attachLoader(pattern: string, loader: Loader<any>): RouterBuilder;
|
|
162
|
+
/**
|
|
163
|
+
* Mark an already-registered route as having a server-side loader without
|
|
164
|
+
* importing that loader into the client bundle. Used by FS-routing codegen
|
|
165
|
+
* so SPA navigation knows to call the loader endpoint.
|
|
166
|
+
*/
|
|
167
|
+
markLoader(pattern: string): RouterBuilder;
|
|
141
168
|
/**
|
|
142
169
|
* Return a snapshot of every registered route in match order. Useful for
|
|
143
170
|
* prerenderers that need to discover the filesystem routes exposed by
|
|
@@ -181,6 +208,14 @@ interface RouterBuilder {
|
|
|
181
208
|
* @returns Cleanup function
|
|
182
209
|
*/
|
|
183
210
|
hydrate(registry: Record<string, Island<any, any>>, options?: HydrateOptions): () => void;
|
|
211
|
+
/**
|
|
212
|
+
* Hydrate islands on the current pre-rendered page without mounting a route
|
|
213
|
+
* view or enabling client navigation. Intended for `static` mode: each page
|
|
214
|
+
* is a self-contained HTML file; only interactive islands need activation.
|
|
215
|
+
*/
|
|
216
|
+
hydrateStatic(registry: Record<string, Island<any, any>>, options?: {
|
|
217
|
+
root?: Element;
|
|
218
|
+
}): () => void;
|
|
184
219
|
}
|
|
185
220
|
/** Path of the loader endpoint served by the Vite plugin / production adapter. */
|
|
186
221
|
declare const LOADER_ENDPOINT = "/__ilha/loader";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as loader, B as useRoute, C as RouterView, D as enableLinkInterception, E as defineLayout, F as routeHash, G as setHistoryMode, H as wrapLayout, I as routeParams, L as routePath, M as prefetch, N as prime, O as error, P as redirect, R as routeSearch, S as RouterOptions, T as composeLoaders, U as HistoryMode, V as wrapError, W as getHistoryMode, _ as RouteRecord, a as InferLoader, b as RouterLink, c as LinkInterceptionOptions, d as LoaderError, f as MergeLoaders, g as RenderResponse, h as Redirect, i as HydrateOptions, j as navigate, k as isActive, l as Loader, m as NavigateOptions, n as ErrorHandler, o as LOADER_ENDPOINT, p as MountOptions, r as HydratableRenderOptions, s as LayoutHandler, t as AppError, u as LoaderContext, v as RouteSnapshot, w as _default, x as RouterMode, y as RouterBuilder, z as router } from "./index-
|
|
1
|
+
import { A as loader, B as useRoute, C as RouterView, D as enableLinkInterception, E as defineLayout, F as routeHash, G as setHistoryMode, H as wrapLayout, I as routeParams, L as routePath, M as prefetch, N as prime, O as error, P as redirect, R as routeSearch, S as RouterOptions, T as composeLoaders, U as HistoryMode, V as wrapError, W as getHistoryMode, _ as RouteRecord, a as InferLoader, b as RouterLink, c as LinkInterceptionOptions, d as LoaderError, f as MergeLoaders, g as RenderResponse, h as Redirect, i as HydrateOptions, j as navigate, k as isActive, l as Loader, m as NavigateOptions, n as ErrorHandler, o as LOADER_ENDPOINT, p as MountOptions, r as HydratableRenderOptions, s as LayoutHandler, t as AppError, u as LoaderContext, v as RouteSnapshot, w as _default, x as RouterMode, y as RouterBuilder, z as router } from "./index-DZA_1KrG.js";
|
|
2
2
|
export { AppError, ErrorHandler, HistoryMode, HydratableRenderOptions, HydrateOptions, InferLoader, LOADER_ENDPOINT, LayoutHandler, LinkInterceptionOptions, Loader, LoaderContext, LoaderError, MergeLoaders, MountOptions, NavigateOptions, Redirect, RenderResponse, RouteRecord, RouteSnapshot, RouterBuilder, RouterLink, RouterMode, RouterOptions, RouterView, composeLoaders, _default as default, defineLayout, enableLinkInterception, error, getHistoryMode, isActive, loader, navigate, prefetch, prime, redirect, routeHash, routeParams, routePath, routeSearch, router, setHistoryMode, useRoute, wrapError, wrapLayout };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as wrapError, E as setHistoryMode, S as useRoute, T as getHistoryMode, _ as routeParams, a as RouterView, b as router, c as enableLinkInterception, d as loader, f as navigate, g as routeHash, h as redirect, i as RouterLink, l as error, m as prime, n as LoaderError, o as composeLoaders, p as prefetch, r as Redirect, s as defineLayout, t as LOADER_ENDPOINT, u as isActive, v as routePath, w as wrapLayout, x as src_default, y as routeSearch } from "./src-
|
|
1
|
+
import { C as wrapError, E as setHistoryMode, S as useRoute, T as getHistoryMode, _ as routeParams, a as RouterView, b as router, c as enableLinkInterception, d as loader, f as navigate, g as routeHash, h as redirect, i as RouterLink, l as error, m as prime, n as LoaderError, o as composeLoaders, p as prefetch, r as Redirect, s as defineLayout, t as LOADER_ENDPOINT, u as isActive, v as routePath, w as wrapLayout, x as src_default, y as routeSearch } from "./src-BP38YTMC.js";
|
|
2
2
|
export { LOADER_ENDPOINT, LoaderError, Redirect, RouterLink, RouterView, composeLoaders, src_default as default, defineLayout, enableLinkInterception, error, getHistoryMode, isActive, loader, navigate, prefetch, prime, redirect, routeHash, routeParams, routePath, routeSearch, router, setHistoryMode, useRoute, wrapError, wrapLayout };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as _$unplugin from "unplugin";
|
|
2
|
+
|
|
3
|
+
//#region src/codegen.d.ts
|
|
4
|
+
type PagesMode = "spa" | "static";
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/plugin.d.ts
|
|
7
|
+
interface IlhaPagesOptions {
|
|
8
|
+
/** Directory containing page files. Default: `src/pages` */
|
|
9
|
+
dir?: string;
|
|
10
|
+
/** Output path for the generated routes + registry file. Default: `.ilha/routes.ts` */
|
|
11
|
+
generated?: string;
|
|
12
|
+
/**
|
|
13
|
+
* File-system router navigation mode.
|
|
14
|
+
* - `spa` — full client route graph with SSR/hydration and client navigation.
|
|
15
|
+
* - `static` — island registry only; no route graph bundled into the client.
|
|
16
|
+
* Default: `spa`.
|
|
17
|
+
*/
|
|
18
|
+
mode?: PagesMode;
|
|
19
|
+
/**
|
|
20
|
+
* When `false`, internal `<a>` clicks are not intercepted — browser performs
|
|
21
|
+
* full document navigations. Only meaningful in `spa` mode.
|
|
22
|
+
* Default: `true`.
|
|
23
|
+
*/
|
|
24
|
+
interceptLinks?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare const ilhaPages: _$unplugin.UnpluginInstance<IlhaPagesOptions | undefined, boolean>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { ilhaPages as n, IlhaPagesOptions as t };
|
|
@@ -140,13 +140,15 @@ function validateEntries(entries, pagesDir) {
|
|
|
140
140
|
}
|
|
141
141
|
async function generate(pagesDir, outFile, options = {}) {
|
|
142
142
|
const mode = options.mode ?? "spa";
|
|
143
|
+
const interceptLinks = options.interceptLinks;
|
|
144
|
+
const isStatic = mode === "static";
|
|
143
145
|
const entries = sortEntries(await scanPages(pagesDir));
|
|
144
146
|
validateEntries(entries, pagesDir);
|
|
145
147
|
const rel = (abs) => {
|
|
146
148
|
const r = toPosix(relative(dirname(outFile), abs));
|
|
147
149
|
return r.startsWith(".") ? r : `./${r}`;
|
|
148
150
|
};
|
|
149
|
-
const imports = [`import { router, wrapLayout, wrapError } from "@ilha/router";`, `import type { Island } from "ilha";`];
|
|
151
|
+
const imports = isStatic ? [`import type { Island } from "ilha";`] : [`import { router, wrapLayout, wrapError } from "@ilha/router";`, `import type { Island } from "ilha";`];
|
|
150
152
|
const wrappedIslandLines = [];
|
|
151
153
|
const registryLines = [];
|
|
152
154
|
const routeLines = [];
|
|
@@ -154,19 +156,26 @@ async function generate(pagesDir, outFile, options = {}) {
|
|
|
154
156
|
for (const [i, entry] of entries.entries()) {
|
|
155
157
|
const pageId = `_page${i}`;
|
|
156
158
|
imports.push(`import { default as ${pageId} } from ${JSON.stringify(clientImport(entry.file))};`);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
if (!isStatic) {
|
|
160
|
+
for (const [j, l] of entry.layouts.entries()) imports.push(`import { default as _layout${i}_${j} } from ${JSON.stringify(clientImport(l))};`);
|
|
161
|
+
for (const [j, e] of entry.errors.entries()) imports.push(`import { default as _error${i}_${j} } from ${JSON.stringify(clientImport(e))};`);
|
|
162
|
+
}
|
|
159
163
|
let expr = pageId;
|
|
160
|
-
|
|
161
|
-
|
|
164
|
+
if (!isStatic) {
|
|
165
|
+
for (let j = entry.errors.length - 1; j >= 0; j--) expr = `wrapError(_error${i}_${j}, ${expr})`;
|
|
166
|
+
for (let j = entry.layouts.length - 1; j >= 0; j--) expr = `wrapLayout(_layout${i}_${j}, ${expr})`;
|
|
167
|
+
}
|
|
162
168
|
const wrappedId = `_wrapped${i}`;
|
|
163
169
|
wrappedIslandLines.push(`const ${wrappedId} = ${expr};`);
|
|
164
170
|
registryLines.push(` ${JSON.stringify(entry.name)}: ${wrappedId}` + (i < entries.length - 1 ? "," : ""));
|
|
165
|
-
routeLines.push(` .route(${JSON.stringify(entry.pattern)}, ${wrappedId})`);
|
|
171
|
+
if (!isStatic) routeLines.push(` .route(${JSON.stringify(entry.pattern)}, ${wrappedId})` + (entry.hasLoader || entry.loaderLayouts.length > 0 ? `.markLoader(${JSON.stringify(entry.pattern)})` : ""));
|
|
166
172
|
}
|
|
167
|
-
const code = [
|
|
173
|
+
const code = isStatic ? [
|
|
168
174
|
`// @generated by @ilha/router — do not edit`,
|
|
175
|
+
`// static mode: no route graph, no client navigation.`,
|
|
176
|
+
`// Import registry to hydrate islands; use pageRouter.hydrateStatic(registry).`,
|
|
169
177
|
``,
|
|
178
|
+
`import { router as _router } from "@ilha/router";`,
|
|
170
179
|
...imports,
|
|
171
180
|
``,
|
|
172
181
|
...wrappedIslandLines,
|
|
@@ -175,12 +184,28 @@ async function generate(pagesDir, outFile, options = {}) {
|
|
|
175
184
|
...registryLines,
|
|
176
185
|
`};`,
|
|
177
186
|
``,
|
|
178
|
-
`export const pageRouter =
|
|
187
|
+
`export const pageRouter = _router({ mode: "static" });`
|
|
188
|
+
].join("\n") : [
|
|
189
|
+
`// @generated by @ilha/router — do not edit`,
|
|
190
|
+
``,
|
|
191
|
+
...imports,
|
|
192
|
+
``,
|
|
193
|
+
...wrappedIslandLines,
|
|
194
|
+
``,
|
|
195
|
+
`export const registry: Record<string, Island<any, any>> = {`,
|
|
196
|
+
...registryLines,
|
|
197
|
+
`};`,
|
|
198
|
+
``,
|
|
199
|
+
`export const pageRouter = router(${interceptLinks === false ? `{ interceptLinks: false }` : ""})`,
|
|
179
200
|
...routeLines,
|
|
180
201
|
` ;`
|
|
181
202
|
].join("\n");
|
|
182
203
|
await mkdir(dirname(outFile), { recursive: true });
|
|
183
204
|
const routesChanged = await writeIfChanged(outFile, code);
|
|
205
|
+
if (isStatic) {
|
|
206
|
+
if (routesChanged) await generateTypes(outFile);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
184
209
|
const loadersFile = join(dirname(outFile), "loaders.ts");
|
|
185
210
|
const loadersChanged = await writeIfChanged(loadersFile, buildLoadersFile(entries, loadersFile, outFile));
|
|
186
211
|
if (routesChanged || loadersChanged) await generateTypes(outFile);
|
|
@@ -286,7 +311,10 @@ function createPagesPluginState(options) {
|
|
|
286
311
|
};
|
|
287
312
|
const regen = async () => {
|
|
288
313
|
try {
|
|
289
|
-
await generate(pagesDir, outFile, {
|
|
314
|
+
await generate(pagesDir, outFile, {
|
|
315
|
+
mode: options.mode,
|
|
316
|
+
interceptLinks: options.interceptLinks
|
|
317
|
+
});
|
|
290
318
|
} catch (e) {
|
|
291
319
|
console.error("[ilha:pages] codegen failed:", e);
|
|
292
320
|
}
|
package/dist/rolldown.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as wrapLayout, V as wrapError, n as ErrorHandler, s as LayoutHandler, t as AppError, v as RouteSnapshot } from "./index-
|
|
2
|
-
import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-
|
|
1
|
+
import { H as wrapLayout, V as wrapError, n as ErrorHandler, s as LayoutHandler, t as AppError, v as RouteSnapshot } from "./index-DZA_1KrG.js";
|
|
2
|
+
import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-BizQQLsn.js";
|
|
3
3
|
import * as _$unplugin from "unplugin";
|
|
4
4
|
|
|
5
5
|
//#region src/rolldown.d.ts
|
package/dist/rolldown.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as wrapError, w as wrapLayout } from "./src-
|
|
2
|
-
import { t as ilhaPages } from "./plugin-
|
|
1
|
+
import { C as wrapError, w as wrapLayout } from "./src-BP38YTMC.js";
|
|
2
|
+
import { t as ilhaPages } from "./plugin-C-TVH3XD.js";
|
|
3
3
|
//#region src/rolldown.ts
|
|
4
4
|
/** Rolldown plugin — use via `@ilha/router/rolldown`. */
|
|
5
5
|
function pages(options = {}) {
|
package/dist/rspack.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as wrapLayout, V as wrapError, n as ErrorHandler, s as LayoutHandler, t as AppError, v as RouteSnapshot } from "./index-
|
|
2
|
-
import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-
|
|
1
|
+
import { H as wrapLayout, V as wrapError, n as ErrorHandler, s as LayoutHandler, t as AppError, v as RouteSnapshot } from "./index-DZA_1KrG.js";
|
|
2
|
+
import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-BizQQLsn.js";
|
|
3
3
|
import * as _$unplugin from "unplugin";
|
|
4
4
|
|
|
5
5
|
//#region src/rspack.d.ts
|
package/dist/rspack.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as wrapError, w as wrapLayout } from "./src-
|
|
2
|
-
import { t as ilhaPages } from "./plugin-
|
|
1
|
+
import { C as wrapError, w as wrapLayout } from "./src-BP38YTMC.js";
|
|
2
|
+
import { t as ilhaPages } from "./plugin-C-TVH3XD.js";
|
|
3
3
|
//#region src/rspack.ts
|
|
4
4
|
/** Rspack plugin — use via `@ilha/router/rspack`. */
|
|
5
5
|
function pages(options = {}) {
|
|
@@ -349,7 +349,7 @@ function prefetch(pathWithSearch) {
|
|
|
349
349
|
if (!isBrowser) return;
|
|
350
350
|
if (prefetchCache.has(pathWithSearch)) return;
|
|
351
351
|
const pathOnly = pathWithSearch.split("?")[0] ?? "";
|
|
352
|
-
if (!findRoute(_rou3, "GET", pathOnly)?.data?.
|
|
352
|
+
if (!findRoute(_rou3, "GET", pathOnly)?.data?.hasLoader) return;
|
|
353
353
|
const promise = fetchLoaderData(pathWithSearch).catch((e) => {
|
|
354
354
|
return {
|
|
355
355
|
kind: "error",
|
|
@@ -369,7 +369,7 @@ async function mountRouteWithHydration(island, host, pathWithSearch, signal, reg
|
|
|
369
369
|
host.innerHTML = `<div data-router-empty></div>`;
|
|
370
370
|
return () => {};
|
|
371
371
|
}
|
|
372
|
-
const hasLoader = !!findRoute(_rou3, "GET", pathWithSearch.split("?")[0] ?? "")?.data?.
|
|
372
|
+
const hasLoader = !!findRoute(_rou3, "GET", pathWithSearch.split("?")[0] ?? "")?.data?.hasLoader;
|
|
373
373
|
let props = {};
|
|
374
374
|
const loaderResult = hasLoader ? await fetchLoaderData(pathWithSearch, signal) : {
|
|
375
375
|
kind: "data",
|
|
@@ -579,6 +579,7 @@ async function executeLoader(loader, url, params, request, signal) {
|
|
|
579
579
|
}
|
|
580
580
|
function router(options = {}) {
|
|
581
581
|
const mode = options.mode ?? "spa";
|
|
582
|
+
const defaultInterceptLinks = options.interceptLinks !== false;
|
|
582
583
|
_records = [];
|
|
583
584
|
_rou3 = createRouter();
|
|
584
585
|
_islandToPattern = /* @__PURE__ */ new Map();
|
|
@@ -587,14 +588,17 @@ function router(options = {}) {
|
|
|
587
588
|
let _linkCleanup = null;
|
|
588
589
|
const builder = {
|
|
589
590
|
route(pattern, island, loader) {
|
|
591
|
+
const hasLoader = !!loader;
|
|
590
592
|
const data = {
|
|
591
593
|
island,
|
|
592
|
-
loader
|
|
594
|
+
loader,
|
|
595
|
+
hasLoader
|
|
593
596
|
};
|
|
594
597
|
_records.push({
|
|
595
598
|
pattern,
|
|
596
599
|
island,
|
|
597
|
-
loader
|
|
600
|
+
loader,
|
|
601
|
+
hasLoader
|
|
598
602
|
});
|
|
599
603
|
addRoute(_rou3, "GET", pattern, data);
|
|
600
604
|
_patternToData.set(pattern, data);
|
|
@@ -608,15 +612,37 @@ function router(options = {}) {
|
|
|
608
612
|
return builder;
|
|
609
613
|
}
|
|
610
614
|
data.loader = loader;
|
|
615
|
+
data.hasLoader = true;
|
|
611
616
|
const rec = _records.find((r) => r.pattern === pattern);
|
|
612
|
-
if (rec)
|
|
617
|
+
if (rec) {
|
|
618
|
+
rec.loader = loader;
|
|
619
|
+
rec.hasLoader = true;
|
|
620
|
+
}
|
|
621
|
+
return builder;
|
|
622
|
+
},
|
|
623
|
+
markLoader(pattern) {
|
|
624
|
+
const data = _patternToData.get(pattern);
|
|
625
|
+
if (!data) {
|
|
626
|
+
console.warn(`[ilha-router] markLoader("${pattern}"): pattern was never registered via .route(). The loader marker will be ignored.`);
|
|
627
|
+
return builder;
|
|
628
|
+
}
|
|
629
|
+
data.hasLoader = true;
|
|
630
|
+
const rec = _records.find((r) => r.pattern === pattern);
|
|
631
|
+
if (rec) rec.hasLoader = true;
|
|
613
632
|
return builder;
|
|
614
633
|
},
|
|
615
634
|
routes() {
|
|
616
635
|
return _records.map((record) => ({ ...record }));
|
|
617
636
|
},
|
|
618
637
|
prime,
|
|
619
|
-
|
|
638
|
+
hydrateStatic(registry, options = {}) {
|
|
639
|
+
if (!isBrowser) return () => {};
|
|
640
|
+
const root = options.root ?? document.body;
|
|
641
|
+
prime();
|
|
642
|
+
const { unmount } = mount(registry, { root });
|
|
643
|
+
return unmount;
|
|
644
|
+
},
|
|
645
|
+
mount(target, { hydrate = false, registry, interceptLinks: mountInterceptLinks } = {}) {
|
|
620
646
|
if (!isBrowser) {
|
|
621
647
|
console.warn("[ilha-router] mount() called in a non-browser environment");
|
|
622
648
|
return () => {};
|
|
@@ -627,9 +653,13 @@ function router(options = {}) {
|
|
|
627
653
|
return () => {};
|
|
628
654
|
}
|
|
629
655
|
syncRouteFromLocation();
|
|
656
|
+
if (mode === "static") {
|
|
657
|
+
console.warn("[ilha-router] router.mount() called in static mode. Use router.hydrateStatic(registry) instead.");
|
|
658
|
+
return () => {};
|
|
659
|
+
}
|
|
630
660
|
const popHandler = () => syncRouteFromLocation();
|
|
631
661
|
_navChangeCleanup = getAdapter().onChange(popHandler);
|
|
632
|
-
_linkCleanup =
|
|
662
|
+
_linkCleanup = mountInterceptLinks ?? defaultInterceptLinks ? enableLinkInterception(document) : null;
|
|
633
663
|
let unmountView = null;
|
|
634
664
|
let navAbort = null;
|
|
635
665
|
if (hydrate) {
|
|
@@ -693,7 +723,7 @@ function router(options = {}) {
|
|
|
693
723
|
const viewHost = host?.querySelector("[data-router-view]");
|
|
694
724
|
if (!viewHost) return;
|
|
695
725
|
const loc = getAdapter().readLocation();
|
|
696
|
-
const result = !!findRoute(_rou3, "GET", loc.pathname)?.data?.
|
|
726
|
+
const result = !!findRoute(_rou3, "GET", loc.pathname)?.data?.hasLoader ? await fetchLoaderData(loc.pathname + loc.search, signal) : {
|
|
697
727
|
kind: "data",
|
|
698
728
|
data: {}
|
|
699
729
|
};
|
|
@@ -823,7 +853,8 @@ function router(options = {}) {
|
|
|
823
853
|
const { unmount } = mount(registry, { root });
|
|
824
854
|
const unmountRouter = this.mount(target, {
|
|
825
855
|
hydrate: true,
|
|
826
|
-
registry
|
|
856
|
+
registry,
|
|
857
|
+
interceptLinks: options.interceptLinks
|
|
827
858
|
});
|
|
828
859
|
return () => {
|
|
829
860
|
unmount();
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { H as wrapLayout, V as wrapError, n as ErrorHandler, s as LayoutHandler, t as AppError, v as RouteSnapshot } from "./index-
|
|
3
|
-
import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-
|
|
2
|
+
import { H as wrapLayout, V as wrapError, n as ErrorHandler, s as LayoutHandler, t as AppError, v as RouteSnapshot } from "./index-DZA_1KrG.js";
|
|
3
|
+
import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-BizQQLsn.js";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
import * as http from "node:http";
|
|
6
6
|
import { Agent, ClientRequest, ClientRequestArgs, OutgoingHttpHeaders } from "node:http";
|
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as wrapError, w as wrapLayout } from "./src-
|
|
2
|
-
import { t as ilhaPages } from "./plugin-
|
|
1
|
+
import { C as wrapError, w as wrapLayout } from "./src-BP38YTMC.js";
|
|
2
|
+
import { t as ilhaPages } from "./plugin-C-TVH3XD.js";
|
|
3
3
|
//#region src/vite.ts
|
|
4
4
|
/** Vite plugin — use via `@ilha/router/vite`. */
|
|
5
5
|
function pages(options = {}) {
|
package/package.json
CHANGED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as _$unplugin from "unplugin";
|
|
2
|
-
|
|
3
|
-
//#region src/codegen.d.ts
|
|
4
|
-
type PagesMode = "spa" | "mpa";
|
|
5
|
-
//#endregion
|
|
6
|
-
//#region src/plugin.d.ts
|
|
7
|
-
interface IlhaPagesOptions {
|
|
8
|
-
/** Directory containing page files. Default: `src/pages` */
|
|
9
|
-
dir?: string;
|
|
10
|
-
/** Output path for the generated routes + registry file. Default: `.ilha/routes.ts` */
|
|
11
|
-
generated?: string;
|
|
12
|
-
/**
|
|
13
|
-
* File-system router navigation mode. `spa` intercepts in-app links and
|
|
14
|
-
* renders routes client-side; `mpa` leaves links to the browser for full
|
|
15
|
-
* document navigations. Default: `spa`.
|
|
16
|
-
*/
|
|
17
|
-
mode?: PagesMode;
|
|
18
|
-
}
|
|
19
|
-
declare const ilhaPages: _$unplugin.UnpluginInstance<IlhaPagesOptions | undefined, boolean>;
|
|
20
|
-
//#endregion
|
|
21
|
-
export { ilhaPages as n, IlhaPagesOptions as t };
|