@ilha/router 0.5.1 → 0.6.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/README.md CHANGED
@@ -53,9 +53,9 @@ export default defineEventHandler((event) => {
53
53
  ### SSR + Client Hydration (recommended)
54
54
 
55
55
  ```ts
56
- // routes/[...].ts — Nitro handler
57
- import { pageRouter } from "ilha:pages";
58
- import { registry } from "ilha:registry";
56
+ // routes/[...].ts — Nitro handler (SSR/prerender)
57
+ import { pageRouter, registry } from "ilha:pages/server";
58
+ import "ilha:loaders"; // ← wire server-only loaders
59
59
 
60
60
  export default defineEventHandler(async (event) => {
61
61
  const html = await pageRouter.renderHydratable(event.node.req.url ?? "/", registry);
@@ -67,8 +67,7 @@ export default defineEventHandler(async (event) => {
67
67
 
68
68
  ```ts
69
69
  // src/client.ts — browser entry
70
- import { pageRouter } from "ilha:pages";
71
- import { registry } from "ilha:registry";
70
+ import { pageRouter, registry } from "ilha:pages/client";
72
71
 
73
72
  pageRouter.hydrate(registry);
74
73
  ```
@@ -916,18 +915,19 @@ export default ((error, route) =>
916
915
 
917
916
  ### Virtual modules
918
917
 
919
- The plugin exposes three virtual modules:
918
+ The plugin exposes separate server and client virtual modules. **Always use the explicit `/server` or `/client` path** — they resolve to different generated files with different import strategies.
920
919
 
921
- | Module | Export | Description |
922
- | --------------- | ------------ | -------------------------------------------- |
923
- | `ilha:pages` | `pageRouter` | A `RouterBuilder` with all routes registered |
924
- | `ilha:registry` | `registry` | `Record<string, Island>` for hydration |
925
- | `ilha:loaders` | — | Side-effect import that wires server loaders |
920
+ | Module | Exports | Use for |
921
+ | ------------------- | ------------------------ | -------------------------------------- |
922
+ | `ilha:pages/server` | `pageRouter`, `registry` | SSR, prerender, Nitro handlers |
923
+ | `ilha:pages/client` | `pageRouter`, `registry` | Browser hydration entry |
924
+ | `ilha:loaders` | — | Server-only side-effect: wires loaders |
925
+
926
+ The server module imports page/layout/error modules **without** `?client` — raw imports so SSR sees full JSX including compound component render parts. The client module imports with `?client` which strips server-only `load` exports from the browser bundle.
926
927
 
927
928
  ```ts
928
- // routes/[...].ts — Nitro catch-all handler
929
- import { pageRouter } from "ilha:pages";
930
- import { registry } from "ilha:registry";
929
+ // routes/[...].ts — SSR/prerender
930
+ import { pageRouter, registry } from "ilha:pages/server";
931
931
  import "ilha:loaders"; // ← wire server loaders
932
932
 
933
933
  export default defineEventHandler(async (event) => {
@@ -940,18 +940,26 @@ export default defineEventHandler(async (event) => {
940
940
 
941
941
  ```ts
942
942
  // src/client.ts — browser entry
943
- import { pageRouter } from "ilha:pages";
944
- import { registry } from "ilha:registry";
943
+ import { pageRouter, registry } from "ilha:pages/client";
945
944
 
946
945
  pageRouter.hydrate(registry);
947
946
  ```
948
947
 
948
+ For `static` MPA mode:
949
+
950
+ ```ts
951
+ // src/entry-client.ts — static/SSG browser entry
952
+ import { pageRouter, registry } from "ilha:pages/client";
953
+
954
+ pageRouter.hydrateStatic(registry);
955
+ ```
956
+
949
957
  ### Plugin options
950
958
 
951
959
  ```ts
952
960
  pages({
953
961
  dir: "src/pages", // pages directory (default: "src/pages")
954
- generated: ".ilha/routes.ts", // generated file output (default: ".ilha/routes.ts")
962
+ outDir: ".ilha", // output directory for generated files (default: ".ilha")
955
963
  mode: "spa", // "spa" | "static" (default: "spa")
956
964
  interceptLinks: true, // only meaningful in spa mode (default: true)
957
965
  });
@@ -138,44 +138,55 @@ function validateEntries(entries, pagesDir) {
138
138
  else seenNames.set(entry.name, entry.file);
139
139
  }
140
140
  }
141
- async function generate(pagesDir, outFile, options = {}) {
141
+ function resolveGeneratedPaths(outDir) {
142
+ return {
143
+ serverFile: join(outDir, "pages.server.ts"),
144
+ clientFile: join(outDir, "pages.client.ts"),
145
+ loadersFile: join(outDir, "loaders.ts")
146
+ };
147
+ }
148
+ async function generate(pagesDir, outDir, options = {}) {
142
149
  const mode = options.mode ?? "spa";
143
150
  const interceptLinks = options.interceptLinks;
144
151
  const isStatic = mode === "static";
145
152
  const entries = sortEntries(await scanPages(pagesDir));
146
153
  validateEntries(entries, pagesDir);
154
+ await mkdir(outDir, { recursive: true });
155
+ const { serverFile, clientFile, loadersFile } = resolveGeneratedPaths(outDir);
156
+ const serverChanged = await writeIfChanged(serverFile, buildServerFile(entries, serverFile));
157
+ const clientChanged = await writeIfChanged(clientFile, buildClientFile(entries, clientFile, {
158
+ isStatic,
159
+ interceptLinks
160
+ }));
161
+ if (!isStatic) await writeIfChanged(loadersFile, buildLoadersFile(entries, loadersFile, serverFile));
162
+ if (serverChanged || clientChanged) await generateTypes(outDir);
163
+ }
164
+ function buildServerFile(entries, serverFile) {
147
165
  const rel = (abs) => {
148
- const r = toPosix(relative(dirname(outFile), abs));
166
+ const r = toPosix(relative(dirname(serverFile), abs));
149
167
  return r.startsWith(".") ? r : `./${r}`;
150
168
  };
151
- const imports = isStatic ? [`import type { Island } from "ilha";`] : [`import { router, wrapLayout, wrapError } from "@ilha/router";`, `import type { Island } from "ilha";`];
169
+ const imports = [`import { router, wrapLayout, wrapError } from "@ilha/router";`, `import type { Island } from "ilha";`];
152
170
  const wrappedIslandLines = [];
153
171
  const registryLines = [];
154
172
  const routeLines = [];
155
- const clientImport = (abs) => `${rel(abs)}?client`;
156
173
  for (const [i, entry] of entries.entries()) {
157
- const pageId = `_page${i}`;
158
- imports.push(`import { default as ${pageId} } from ${JSON.stringify(clientImport(entry.file))};`);
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
- }
163
- let expr = pageId;
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
- }
174
+ imports.push(`import { default as _page${i} } from ${JSON.stringify(rel(entry.file))};`);
175
+ for (const [j, l] of entry.layouts.entries()) imports.push(`import { default as _layout${i}_${j} } from ${JSON.stringify(rel(l))};`);
176
+ for (const [j, e] of entry.errors.entries()) imports.push(`import { default as _error${i}_${j} } from ${JSON.stringify(rel(e))};`);
177
+ let expr = `_page${i}`;
178
+ for (let j = entry.errors.length - 1; j >= 0; j--) expr = `wrapError(_error${i}_${j}, ${expr})`;
179
+ for (let j = entry.layouts.length - 1; j >= 0; j--) expr = `wrapLayout(_layout${i}_${j}, ${expr})`;
168
180
  const wrappedId = `_wrapped${i}`;
169
181
  wrappedIslandLines.push(`const ${wrappedId} = ${expr};`);
170
182
  registryLines.push(` ${JSON.stringify(entry.name)}: ${wrappedId}` + (i < entries.length - 1 ? "," : ""));
171
- if (!isStatic) routeLines.push(` .route(${JSON.stringify(entry.pattern)}, ${wrappedId})` + (entry.hasLoader || entry.loaderLayouts.length > 0 ? `.markLoader(${JSON.stringify(entry.pattern)})` : ""));
183
+ routeLines.push(` .route(${JSON.stringify(entry.pattern)}, ${wrappedId})` + (entry.hasLoader || entry.loaderLayouts.length > 0 ? `.markLoader(${JSON.stringify(entry.pattern)})` : ""));
172
184
  }
173
- const code = isStatic ? [
185
+ return [
174
186
  `// @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).`,
187
+ `// Server module. Use for SSR and SSG/prerender.`,
188
+ `// Import via: import { pageRouter, registry } from "ilha:pages/server";`,
177
189
  ``,
178
- `import { router as _router } from "@ilha/router";`,
179
190
  ...imports,
180
191
  ``,
181
192
  ...wrappedIslandLines,
@@ -184,9 +195,39 @@ async function generate(pagesDir, outFile, options = {}) {
184
195
  ...registryLines,
185
196
  `};`,
186
197
  ``,
187
- `export const pageRouter = _router({ mode: "static" });`
188
- ].join("\n") : [
198
+ `export const pageRouter = router()`,
199
+ ...routeLines,
200
+ ` ;`
201
+ ].join("\n");
202
+ }
203
+ function buildClientFile(entries, clientFile, opts) {
204
+ const { isStatic, interceptLinks } = opts;
205
+ const rel = (abs) => {
206
+ const r = toPosix(relative(dirname(clientFile), abs));
207
+ return r.startsWith(".") ? r : `./${r}`;
208
+ };
209
+ const clientImport = (abs) => `${rel(abs)}?client`;
210
+ const imports = isStatic ? [`import { router as _router, wrapLayout, wrapError } from "@ilha/router";`, `import type { Island } from "ilha";`] : [`import { router, wrapLayout, wrapError } from "@ilha/router";`, `import type { Island } from "ilha";`];
211
+ const wrappedIslandLines = [];
212
+ const registryLines = [];
213
+ const routeLines = [];
214
+ for (const [i, entry] of entries.entries()) {
215
+ imports.push(`import { default as _page${i} } from ${JSON.stringify(clientImport(entry.file))};`);
216
+ for (const [j, l] of entry.layouts.entries()) imports.push(`import { default as _layout${i}_${j} } from ${JSON.stringify(clientImport(l))};`);
217
+ for (const [j, e] of entry.errors.entries()) imports.push(`import { default as _error${i}_${j} } from ${JSON.stringify(clientImport(e))};`);
218
+ let expr = `_page${i}`;
219
+ for (let j = entry.errors.length - 1; j >= 0; j--) expr = `wrapError(_error${i}_${j}, ${expr})`;
220
+ for (let j = entry.layouts.length - 1; j >= 0; j--) expr = `wrapLayout(_layout${i}_${j}, ${expr})`;
221
+ const wrappedId = `_wrapped${i}`;
222
+ wrappedIslandLines.push(`const ${wrappedId} = ${expr};`);
223
+ registryLines.push(` ${JSON.stringify(entry.name)}: ${wrappedId}` + (i < entries.length - 1 ? "," : ""));
224
+ if (!isStatic) routeLines.push(` .route(${JSON.stringify(entry.pattern)}, ${wrappedId})` + (entry.hasLoader || entry.loaderLayouts.length > 0 ? `.markLoader(${JSON.stringify(entry.pattern)})` : ""));
225
+ }
226
+ const routerExpr = isStatic ? `_router({ mode: "static" })` : `router(${interceptLinks === false ? `{ interceptLinks: false }` : ""})`;
227
+ const lines = [
189
228
  `// @generated by @ilha/router — do not edit`,
229
+ `// Client module. Use for browser hydration.`,
230
+ `// Import via: import { pageRouter, registry } from "ilha:pages/client";`,
190
231
  ``,
191
232
  ...imports,
192
233
  ``,
@@ -195,22 +236,13 @@ async function generate(pagesDir, outFile, options = {}) {
195
236
  `export const registry: Record<string, Island<any, any>> = {`,
196
237
  ...registryLines,
197
238
  `};`,
198
- ``,
199
- `export const pageRouter = router(${interceptLinks === false ? `{ interceptLinks: false }` : ""})`,
200
- ...routeLines,
201
- ` ;`
202
- ].join("\n");
203
- await mkdir(dirname(outFile), { recursive: true });
204
- const routesChanged = await writeIfChanged(outFile, code);
205
- if (isStatic) {
206
- if (routesChanged) await generateTypes(outFile);
207
- return;
208
- }
209
- const loadersFile = join(dirname(outFile), "loaders.ts");
210
- const loadersChanged = await writeIfChanged(loadersFile, buildLoadersFile(entries, loadersFile, outFile));
211
- if (routesChanged || loadersChanged) await generateTypes(outFile);
239
+ ``
240
+ ];
241
+ if (isStatic) lines.push(`export const pageRouter = ${routerExpr};`);
242
+ else lines.push(`export const pageRouter = ${routerExpr}`, ...routeLines, ` ;`);
243
+ return lines.join("\n");
212
244
  }
213
- function buildLoadersFile(entries, loadersFile, routesFile) {
245
+ function buildLoadersFile(entries, loadersFile, serverFile) {
214
246
  const relFromLoaders = (abs) => {
215
247
  const r = toPosix(relative(dirname(loadersFile), abs));
216
248
  return r.startsWith(".") ? r : `./${r}`;
@@ -223,8 +255,8 @@ function buildLoadersFile(entries, loadersFile, routesFile) {
223
255
  `export {};`,
224
256
  ``
225
257
  ].join("\n");
226
- const routesRel = relFromLoaders(routesFile).replace(/\.tsx?$/, "");
227
- const imports = [`import { pageRouter } from ${JSON.stringify(routesRel)};`];
258
+ const serverRel = relFromLoaders(serverFile).replace(/\.tsx?$/, "");
259
+ const imports = [`import { pageRouter } from ${JSON.stringify(serverRel)};`];
228
260
  let needsComposeLoaders = false;
229
261
  const attachLines = [];
230
262
  for (const [i, entry] of withLoaders.entries()) {
@@ -263,17 +295,21 @@ async function writeIfChanged(file, content) {
263
295
  await writeFile(file, content, "utf8");
264
296
  return true;
265
297
  }
266
- async function generateTypes(outFile) {
267
- await writeIfChanged(outFile.replace(/\.tsx?$/, ".d.ts"), [
298
+ async function generateTypes(outDir) {
299
+ await writeIfChanged(join(outDir, "pages.d.ts"), [
268
300
  `// @generated by @ilha/router — do not edit`,
269
301
  ``,
270
- `declare module "ilha:pages" {`,
302
+ `declare module "ilha:pages/server" {`,
271
303
  ` import type { RouterBuilder } from "@ilha/router";`,
304
+ ` import type { Island } from "ilha";`,
272
305
  ` export const pageRouter: RouterBuilder;`,
306
+ ` export const registry: Record<string, Island<any, any>>;`,
273
307
  `}`,
274
308
  ``,
275
- `declare module "ilha:registry" {`,
309
+ `declare module "ilha:pages/client" {`,
310
+ ` import type { RouterBuilder } from "@ilha/router";`,
276
311
  ` import type { Island } from "ilha";`,
312
+ ` export const pageRouter: RouterBuilder;`,
277
313
  ` export const registry: Record<string, Island<any, any>>;`,
278
314
  `}`,
279
315
  ``,
@@ -283,35 +319,40 @@ async function generateTypes(outFile) {
283
319
  ``
284
320
  ].join("\n"));
285
321
  }
286
- const RESOLVED_PAGES = "\0ilha:pages";
287
- const RESOLVED_REGISTRY = "\0ilha:registry";
322
+ const RESOLVED_PAGES_SERVER = "\0ilha:pages/server";
323
+ const RESOLVED_PAGES_CLIENT = "\0ilha:pages/client";
288
324
  const RESOLVED_LOADERS = "\0ilha:loaders";
289
325
  const RESOLVED_VIRTUAL_IDS = [
290
- RESOLVED_PAGES,
291
- RESOLVED_REGISTRY,
326
+ RESOLVED_PAGES_SERVER,
327
+ RESOLVED_PAGES_CLIENT,
292
328
  RESOLVED_LOADERS
293
329
  ];
294
- /** Query suffix used on page/layout imports in the client-safe routes file. */
330
+ /** Query suffix used on page/layout imports in the client file. */
295
331
  const CLIENT_QUERY = "?client";
296
332
  function resolvePluginPaths(root, options) {
297
333
  const pagesDir = resolve(root, options.dir ?? "src/pages");
298
- const outFile = resolve(root, options.generated ?? ".ilha/routes.ts");
334
+ const outDir = resolve(root, options.outDir ?? ".ilha");
335
+ const { serverFile, clientFile, loadersFile } = resolveGeneratedPaths(outDir);
299
336
  return {
300
337
  pagesDir,
301
- outFile,
302
- loadersFile: join(dirname(outFile), "loaders.ts")
338
+ outDir,
339
+ serverFile,
340
+ clientFile,
341
+ loadersFile
303
342
  };
304
343
  }
305
344
  function createPagesPluginState(options) {
306
345
  let pagesDir;
307
- let outFile;
346
+ let outDir;
347
+ let serverFile;
348
+ let clientFile;
308
349
  let loadersFile;
309
350
  const setPaths = (root) => {
310
- ({pagesDir, outFile, loadersFile} = resolvePluginPaths(root, options));
351
+ ({pagesDir, outDir, serverFile, clientFile, loadersFile} = resolvePluginPaths(root, options));
311
352
  };
312
353
  const regen = async () => {
313
354
  try {
314
- await generate(pagesDir, outFile, {
355
+ await generate(pagesDir, outDir, {
315
356
  mode: options.mode,
316
357
  interceptLinks: options.interceptLinks
317
358
  });
@@ -329,8 +370,14 @@ function createPagesPluginState(options) {
329
370
  get pagesDir() {
330
371
  return pagesDir;
331
372
  },
332
- get outFile() {
333
- return outFile;
373
+ get outDir() {
374
+ return outDir;
375
+ },
376
+ get serverFile() {
377
+ return serverFile;
378
+ },
379
+ get clientFile() {
380
+ return clientFile;
334
381
  },
335
382
  get loadersFile() {
336
383
  return loadersFile;
@@ -346,22 +393,22 @@ async function regenFromPagesChange(state, file, shouldRegen) {
346
393
  await state.regen();
347
394
  }
348
395
  function resolvePagesId(_state, id, importer) {
349
- if (id === "ilha:pages") return RESOLVED_PAGES;
350
- if (id === "ilha:registry") return RESOLVED_REGISTRY;
396
+ if (id === "ilha:pages/server") return RESOLVED_PAGES_SERVER;
397
+ if (id === "ilha:pages/client") return RESOLVED_PAGES_CLIENT;
351
398
  if (id === "ilha:loaders") return RESOLVED_LOADERS;
352
399
  if (id.endsWith("?client")) {
353
400
  const bare = id.slice(0, -7);
354
- return (importer ? resolve(dirname(importer.replace(/\?.*$/, "")), bare) : resolve(bare)) + CLIENT_QUERY;
401
+ return (importer ? resolve(importer.replace(/\?.*$/, ""), "..", bare) : resolve(bare)) + CLIENT_QUERY;
355
402
  }
356
403
  }
357
404
  function loadPagesModule(state, id) {
358
- if (id === "\0ilha:pages") {
359
- const spec = state.outFile.replace(/\.tsx?$/, "");
360
- return `export { pageRouter } from ${JSON.stringify(spec)};`;
405
+ if (id === "\0ilha:pages/server") {
406
+ const spec = state.serverFile.replace(/\.tsx?$/, "");
407
+ return `export { pageRouter, registry } from ${JSON.stringify(spec)};`;
361
408
  }
362
- if (id === "\0ilha:registry") {
363
- const spec = state.outFile.replace(/\.tsx?$/, "");
364
- return `export { registry } from ${JSON.stringify(spec)};`;
409
+ if (id === "\0ilha:pages/client") {
410
+ const spec = state.clientFile.replace(/\.tsx?$/, "");
411
+ return `export { pageRouter, registry } from ${JSON.stringify(spec)};`;
365
412
  }
366
413
  if (id === "\0ilha:loaders") {
367
414
  const spec = state.loadersFile.replace(/\.tsx?$/, "");
@@ -7,8 +7,8 @@ type PagesMode = "spa" | "static";
7
7
  interface IlhaPagesOptions {
8
8
  /** Directory containing page files. Default: `src/pages` */
9
9
  dir?: string;
10
- /** Output path for the generated routes + registry file. Default: `.ilha/routes.ts` */
11
- generated?: string;
10
+ /** Output directory for generated files. Default: `.ilha` */
11
+ outDir?: string;
12
12
  /**
13
13
  * File-system router navigation mode.
14
14
  * - `spa` — full client route graph with SSR/hydration and client navigation.
@@ -1,5 +1,5 @@
1
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";
2
+ import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-rauddckN.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
1
  import { C as wrapError, w as wrapLayout } from "./src-BP38YTMC.js";
2
- import { t as ilhaPages } from "./plugin-C-TVH3XD.js";
2
+ import { t as ilhaPages } from "./plugin-Cq0xpVL8.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
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";
2
+ import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-rauddckN.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
1
  import { C as wrapError, w as wrapLayout } from "./src-BP38YTMC.js";
2
- import { t as ilhaPages } from "./plugin-C-TVH3XD.js";
2
+ import { t as ilhaPages } from "./plugin-Cq0xpVL8.js";
3
3
  //#region src/rspack.ts
4
4
  /** Rspack plugin — use via `@ilha/router/rspack`. */
5
5
  function pages(options = {}) {
package/dist/vite.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
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";
3
+ import { n as ilhaPages, t as IlhaPagesOptions } from "./plugin-rauddckN.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
1
  import { C as wrapError, w as wrapLayout } from "./src-BP38YTMC.js";
2
- import { t as ilhaPages } from "./plugin-C-TVH3XD.js";
2
+ import { t as ilhaPages } from "./plugin-Cq0xpVL8.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,6 +1,6 @@
1
1
  {
2
2
  "name": "@ilha/router",
3
- "version": "0.5.1",
3
+ "version": "0.6.1",
4
4
  "description": "A tiny SPA router for Ilha",
5
5
  "license": "MIT",
6
6
  "author": "Ryuz <ryuzer@proton.me>",