@ilha/router 0.5.1 → 0.6.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 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,43 @@ 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 } 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
+ if (!isStatic) {
217
+ for (const [j, l] of entry.layouts.entries()) imports.push(`import { default as _layout${i}_${j} } from ${JSON.stringify(clientImport(l))};`);
218
+ for (const [j, e] of entry.errors.entries()) imports.push(`import { default as _error${i}_${j} } from ${JSON.stringify(clientImport(e))};`);
219
+ }
220
+ let expr = `_page${i}`;
221
+ if (!isStatic) {
222
+ for (let j = entry.errors.length - 1; j >= 0; j--) expr = `wrapError(_error${i}_${j}, ${expr})`;
223
+ for (let j = entry.layouts.length - 1; j >= 0; j--) expr = `wrapLayout(_layout${i}_${j}, ${expr})`;
224
+ }
225
+ const wrappedId = `_wrapped${i}`;
226
+ wrappedIslandLines.push(`const ${wrappedId} = ${expr};`);
227
+ registryLines.push(` ${JSON.stringify(entry.name)}: ${wrappedId}` + (i < entries.length - 1 ? "," : ""));
228
+ if (!isStatic) routeLines.push(` .route(${JSON.stringify(entry.pattern)}, ${wrappedId})` + (entry.hasLoader || entry.loaderLayouts.length > 0 ? `.markLoader(${JSON.stringify(entry.pattern)})` : ""));
229
+ }
230
+ const routerExpr = isStatic ? `_router({ mode: "static" })` : `router(${interceptLinks === false ? `{ interceptLinks: false }` : ""})`;
231
+ const lines = [
189
232
  `// @generated by @ilha/router — do not edit`,
233
+ `// Client module. Use for browser hydration.`,
234
+ `// Import via: import { pageRouter, registry } from "ilha:pages/client";`,
190
235
  ``,
191
236
  ...imports,
192
237
  ``,
@@ -195,22 +240,13 @@ async function generate(pagesDir, outFile, options = {}) {
195
240
  `export const registry: Record<string, Island<any, any>> = {`,
196
241
  ...registryLines,
197
242
  `};`,
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);
243
+ ``
244
+ ];
245
+ if (isStatic) lines.push(`export const pageRouter = ${routerExpr};`);
246
+ else lines.push(`export const pageRouter = ${routerExpr}`, ...routeLines, ` ;`);
247
+ return lines.join("\n");
212
248
  }
213
- function buildLoadersFile(entries, loadersFile, routesFile) {
249
+ function buildLoadersFile(entries, loadersFile, serverFile) {
214
250
  const relFromLoaders = (abs) => {
215
251
  const r = toPosix(relative(dirname(loadersFile), abs));
216
252
  return r.startsWith(".") ? r : `./${r}`;
@@ -223,8 +259,8 @@ function buildLoadersFile(entries, loadersFile, routesFile) {
223
259
  `export {};`,
224
260
  ``
225
261
  ].join("\n");
226
- const routesRel = relFromLoaders(routesFile).replace(/\.tsx?$/, "");
227
- const imports = [`import { pageRouter } from ${JSON.stringify(routesRel)};`];
262
+ const serverRel = relFromLoaders(serverFile).replace(/\.tsx?$/, "");
263
+ const imports = [`import { pageRouter } from ${JSON.stringify(serverRel)};`];
228
264
  let needsComposeLoaders = false;
229
265
  const attachLines = [];
230
266
  for (const [i, entry] of withLoaders.entries()) {
@@ -263,17 +299,21 @@ async function writeIfChanged(file, content) {
263
299
  await writeFile(file, content, "utf8");
264
300
  return true;
265
301
  }
266
- async function generateTypes(outFile) {
267
- await writeIfChanged(outFile.replace(/\.tsx?$/, ".d.ts"), [
302
+ async function generateTypes(outDir) {
303
+ await writeIfChanged(join(outDir, "pages.d.ts"), [
268
304
  `// @generated by @ilha/router — do not edit`,
269
305
  ``,
270
- `declare module "ilha:pages" {`,
306
+ `declare module "ilha:pages/server" {`,
271
307
  ` import type { RouterBuilder } from "@ilha/router";`,
308
+ ` import type { Island } from "ilha";`,
272
309
  ` export const pageRouter: RouterBuilder;`,
310
+ ` export const registry: Record<string, Island<any, any>>;`,
273
311
  `}`,
274
312
  ``,
275
- `declare module "ilha:registry" {`,
313
+ `declare module "ilha:pages/client" {`,
314
+ ` import type { RouterBuilder } from "@ilha/router";`,
276
315
  ` import type { Island } from "ilha";`,
316
+ ` export const pageRouter: RouterBuilder;`,
277
317
  ` export const registry: Record<string, Island<any, any>>;`,
278
318
  `}`,
279
319
  ``,
@@ -283,35 +323,40 @@ async function generateTypes(outFile) {
283
323
  ``
284
324
  ].join("\n"));
285
325
  }
286
- const RESOLVED_PAGES = "\0ilha:pages";
287
- const RESOLVED_REGISTRY = "\0ilha:registry";
326
+ const RESOLVED_PAGES_SERVER = "\0ilha:pages/server";
327
+ const RESOLVED_PAGES_CLIENT = "\0ilha:pages/client";
288
328
  const RESOLVED_LOADERS = "\0ilha:loaders";
289
329
  const RESOLVED_VIRTUAL_IDS = [
290
- RESOLVED_PAGES,
291
- RESOLVED_REGISTRY,
330
+ RESOLVED_PAGES_SERVER,
331
+ RESOLVED_PAGES_CLIENT,
292
332
  RESOLVED_LOADERS
293
333
  ];
294
- /** Query suffix used on page/layout imports in the client-safe routes file. */
334
+ /** Query suffix used on page/layout imports in the client file. */
295
335
  const CLIENT_QUERY = "?client";
296
336
  function resolvePluginPaths(root, options) {
297
337
  const pagesDir = resolve(root, options.dir ?? "src/pages");
298
- const outFile = resolve(root, options.generated ?? ".ilha/routes.ts");
338
+ const outDir = resolve(root, options.outDir ?? ".ilha");
339
+ const { serverFile, clientFile, loadersFile } = resolveGeneratedPaths(outDir);
299
340
  return {
300
341
  pagesDir,
301
- outFile,
302
- loadersFile: join(dirname(outFile), "loaders.ts")
342
+ outDir,
343
+ serverFile,
344
+ clientFile,
345
+ loadersFile
303
346
  };
304
347
  }
305
348
  function createPagesPluginState(options) {
306
349
  let pagesDir;
307
- let outFile;
350
+ let outDir;
351
+ let serverFile;
352
+ let clientFile;
308
353
  let loadersFile;
309
354
  const setPaths = (root) => {
310
- ({pagesDir, outFile, loadersFile} = resolvePluginPaths(root, options));
355
+ ({pagesDir, outDir, serverFile, clientFile, loadersFile} = resolvePluginPaths(root, options));
311
356
  };
312
357
  const regen = async () => {
313
358
  try {
314
- await generate(pagesDir, outFile, {
359
+ await generate(pagesDir, outDir, {
315
360
  mode: options.mode,
316
361
  interceptLinks: options.interceptLinks
317
362
  });
@@ -329,8 +374,14 @@ function createPagesPluginState(options) {
329
374
  get pagesDir() {
330
375
  return pagesDir;
331
376
  },
332
- get outFile() {
333
- return outFile;
377
+ get outDir() {
378
+ return outDir;
379
+ },
380
+ get serverFile() {
381
+ return serverFile;
382
+ },
383
+ get clientFile() {
384
+ return clientFile;
334
385
  },
335
386
  get loadersFile() {
336
387
  return loadersFile;
@@ -346,22 +397,22 @@ async function regenFromPagesChange(state, file, shouldRegen) {
346
397
  await state.regen();
347
398
  }
348
399
  function resolvePagesId(_state, id, importer) {
349
- if (id === "ilha:pages") return RESOLVED_PAGES;
350
- if (id === "ilha:registry") return RESOLVED_REGISTRY;
400
+ if (id === "ilha:pages/server") return RESOLVED_PAGES_SERVER;
401
+ if (id === "ilha:pages/client") return RESOLVED_PAGES_CLIENT;
351
402
  if (id === "ilha:loaders") return RESOLVED_LOADERS;
352
403
  if (id.endsWith("?client")) {
353
404
  const bare = id.slice(0, -7);
354
- return (importer ? resolve(dirname(importer.replace(/\?.*$/, "")), bare) : resolve(bare)) + CLIENT_QUERY;
405
+ return (importer ? resolve(importer.replace(/\?.*$/, ""), "..", bare) : resolve(bare)) + CLIENT_QUERY;
355
406
  }
356
407
  }
357
408
  function loadPagesModule(state, id) {
358
- if (id === "\0ilha:pages") {
359
- const spec = state.outFile.replace(/\.tsx?$/, "");
360
- return `export { pageRouter } from ${JSON.stringify(spec)};`;
409
+ if (id === "\0ilha:pages/server") {
410
+ const spec = state.serverFile.replace(/\.tsx?$/, "");
411
+ return `export { pageRouter, registry } from ${JSON.stringify(spec)};`;
361
412
  }
362
- if (id === "\0ilha:registry") {
363
- const spec = state.outFile.replace(/\.tsx?$/, "");
364
- return `export { registry } from ${JSON.stringify(spec)};`;
413
+ if (id === "\0ilha:pages/client") {
414
+ const spec = state.clientFile.replace(/\.tsx?$/, "");
415
+ return `export { pageRouter, registry } from ${JSON.stringify(spec)};`;
365
416
  }
366
417
  if (id === "\0ilha:loaders") {
367
418
  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-CJBtP3fl.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-CJBtP3fl.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-CJBtP3fl.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.0",
4
4
  "description": "A tiny SPA router for Ilha",
5
5
  "license": "MIT",
6
6
  "author": "Ryuz <ryuzer@proton.me>",