@ilha/router 0.3.6 → 0.3.8

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
@@ -562,6 +562,8 @@ RouterLink.toString({ href: "/about", label: "About" });
562
562
 
563
563
  Wraps a page island with a layout handler. Used internally by the Vite plugin codegen — also available for manual composition.
564
564
 
565
+ On client hydration, `wrapLayout` mounts the full layout island (layout child slots `p:*` and the keyed page slot `k:page`) from existing SSR DOM — it does not re-render layout markup from serialized props. Interactive components in `+layout.tsx` (state, event handlers, nested islands) hydrate the same way as the page.
566
+
565
567
  ```ts
566
568
  import { wrapLayout } from "@ilha/router";
567
569
 
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-BFZ-RQw6.js";
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-BBvRqv3b.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 };
@@ -180,7 +180,48 @@ function composeLoaders(loaders) {
180
180
  };
181
181
  }
182
182
  function wrapLayout(layout, page) {
183
- return layout(page);
183
+ const Wrapped = layout(Object.assign(page.key("page"), { toString: page.toString.bind(page) }));
184
+ function pageMountHost(host) {
185
+ return host.querySelector("[data-ilha-slot=\"k:page\"]") ?? host;
186
+ }
187
+ function preparePageMountHost(outer, mountHost) {
188
+ if (mountHost.hasAttribute("data-ilha-state")) return;
189
+ const outerState = outer.getAttribute("data-ilha-state");
190
+ if (!outerState) return;
191
+ try {
192
+ const snapshot = JSON.parse(outerState);
193
+ delete snapshot._skipOnMount;
194
+ mountHost.setAttribute("data-ilha-state", JSON.stringify(snapshot));
195
+ } catch {}
196
+ }
197
+ const layoutMount = Wrapped.mount.bind(Wrapped);
198
+ const layoutInternal = Wrapped[ISLAND_MOUNT_INTERNAL];
199
+ function prepareLayoutMountHost(host) {
200
+ preparePageMountHost(host, pageMountHost(host));
201
+ host.removeAttribute("data-ilha-state");
202
+ }
203
+ Wrapped.mount = (host, props) => {
204
+ prepareLayoutMountHost(host);
205
+ return layoutMount(host, props);
206
+ };
207
+ Wrapped[ISLAND_MOUNT_INTERNAL] = (host, props) => {
208
+ prepareLayoutMountHost(host);
209
+ if (typeof layoutInternal === "function") return layoutInternal(host, props);
210
+ return {
211
+ unmount: layoutMount(host, props),
212
+ updateProps: () => {}
213
+ };
214
+ };
215
+ Wrapped.hydratable = async (props, opts) => {
216
+ if (!opts?.name) throw new Error("wrapLayout: hydratable requires options.name");
217
+ const resolvedProps = props ?? {};
218
+ const pageBlock = await page.hydratable(resolvedProps, opts);
219
+ const openTag = pageBlock.match(/^<([a-zA-Z][\w-]*)\s([^>]*)>/);
220
+ if (!openTag) return pageBlock;
221
+ const layoutInner = Wrapped.toString(resolvedProps);
222
+ return `<${openTag[1]} ${openTag[2]}>${layoutInner}</${openTag[1]}>`;
223
+ };
224
+ return Wrapped;
184
225
  }
185
226
  function wrapError(handler, page) {
186
227
  const Wrapper = ilha.render(() => {
@@ -246,6 +287,10 @@ function wrapError(handler, page) {
246
287
  };
247
288
  }
248
289
  };
290
+ Wrapper.hydratable = async (props, opts) => {
291
+ if (!opts?.name) throw new Error("wrapError: hydratable requires options.name");
292
+ return page.hydratable(props ?? {}, opts);
293
+ };
249
294
  return Wrapper;
250
295
  }
251
296
  function defineLayout(layout) {
package/dist/vite.d.ts CHANGED
@@ -18,7 +18,7 @@ import SassEmbedded from "sass-embedded";
18
18
  import Less from "less";
19
19
  import Stylus from "stylus";
20
20
 
21
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/types/hmrPayload.d.ts
21
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/types/hmrPayload.d.ts
22
22
  type HotPayload = ConnectedPayload | PingPayload | UpdatePayload | FullReloadPayload | CustomPayload | ErrorPayload | PrunePayload;
23
23
  interface ConnectedPayload {
24
24
  type: 'connected';
@@ -83,7 +83,7 @@ interface ErrorPayload {
83
83
  };
84
84
  }
85
85
  //#endregion
86
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/dist/node/chunks/moduleRunnerTransport.d.ts
86
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/dist/node/chunks/moduleRunnerTransport.d.ts
87
87
  //#region src/shared/invokeMethods.d.ts
88
88
  interface FetchFunctionOptions {
89
89
  cached?: boolean;
@@ -136,7 +136,7 @@ interface ViteFetchResult {
136
136
  invalidate: boolean;
137
137
  }
138
138
  //#endregion
139
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/types/customEvent.d.ts
139
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/types/customEvent.d.ts
140
140
  interface CustomEventMap {
141
141
  // client events
142
142
  'vite:beforeUpdate': UpdatePayload;
@@ -6297,13 +6297,13 @@ interface TransformOptions$1 extends BindingEnhancedTransformOptions {}
6297
6297
  * @category Utilities
6298
6298
  */
6299
6299
  //#endregion
6300
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/types/internal/esbuildOptions.d.ts
6300
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/types/internal/esbuildOptions.d.ts
6301
6301
  /* eslint-enable @typescript-eslint/ban-ts-comment */
6302
6302
  type EsbuildTarget = string | string[];
6303
6303
  type EsbuildTransformOptions = esbuild.TransformOptions;
6304
6304
  type DepsOptimizerEsbuildOptions = Omit<esbuild.BuildOptions, 'bundle' | 'entryPoints' | 'external' | 'write' | 'watch' | 'outdir' | 'outfile' | 'outbase' | 'outExtension' | 'metafile'>;
6305
6305
  //#endregion
6306
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/types/metadata.d.ts
6306
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/types/metadata.d.ts
6307
6307
  interface AssetMetadata {
6308
6308
  importedAssets: Set<string>;
6309
6309
  importedCss: Set<string>;
@@ -6346,16 +6346,16 @@ declare module 'rolldown' {
6346
6346
  }
6347
6347
  }
6348
6348
  //#endregion
6349
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/types/internal/terserOptions.d.ts
6349
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/types/internal/terserOptions.d.ts
6350
6350
  /* eslint-enable @typescript-eslint/ban-ts-comment */
6351
6351
  type TerserMinifyOptions = Terser.MinifyOptions;
6352
6352
  //#endregion
6353
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/types/internal/lightningcssOptions.d.ts
6353
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/types/internal/lightningcssOptions.d.ts
6354
6354
  /* eslint-enable @typescript-eslint/ban-ts-comment */
6355
6355
  type LightningCSSOptions = Omit<Lightningcss.BundleAsyncOptions<Lightningcss.CustomAtRules>, 'filename' | 'resolver' | 'minify' | 'sourceMap' | 'analyzeDependencies' // properties not overridden by Vite, but does not make sense to set by end users
6356
6356
  | 'inputSourceMap' | 'projectRoot'>;
6357
6357
  //#endregion
6358
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/types/internal/cssPreprocessorOptions.d.ts
6358
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/types/internal/cssPreprocessorOptions.d.ts
6359
6359
  /* eslint-enable @typescript-eslint/ban-ts-comment */
6360
6360
  // https://github.com/type-challenges/type-challenges/issues/29285
6361
6361
  type IsAny<T> = boolean extends (T extends never ? true : false) ? true : false;
@@ -6374,7 +6374,7 @@ declare global {
6374
6374
  interface HTMLLinkElement {}
6375
6375
  }
6376
6376
  //#endregion
6377
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/types/importGlob.d.ts
6377
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/types/importGlob.d.ts
6378
6378
  /**
6379
6379
  * Declare Worker in case DOM is not added to the tsconfig lib causing
6380
6380
  * Worker interface is not defined. For developers with DOM lib added,
@@ -6385,7 +6385,7 @@ declare global {
6385
6385
  interface Worker {}
6386
6386
  }
6387
6387
  //#endregion
6388
- //#region ../../node_modules/.bun/vite@8.0.14+1472ca47ea14e560/node_modules/vite/dist/node/index.d.ts
6388
+ //#region ../../node_modules/.bun/vite@8.0.14+9357385a17cbd143/node_modules/vite/dist/node/index.d.ts
6389
6389
  //#region \0rolldown/runtime.js
6390
6390
  //#endregion
6391
6391
  //#region ../../node_modules/.pnpm/@vitejs+devtools@0.1.24_typescript@6.0.3_vite@packages+vite/node_modules/@vitejs/devtools/dist/cli-commands.d.ts
package/dist/vite.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as wrapError, w as wrapLayout } from "./src-BFZ-RQw6.js";
1
+ import { C as wrapError, w as wrapLayout } from "./src-BBvRqv3b.js";
2
2
  import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
3
3
  import { basename, dirname, extname, join, relative, resolve } from "node:path";
4
4
  //#region src/vite.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ilha/router",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "A tiny SPA router for Ilha",
5
5
  "license": "MIT",
6
6
  "author": "Ryuz <ryuzer@proton.me>",
@@ -30,7 +30,7 @@
30
30
  "test": "bun test"
31
31
  },
32
32
  "dependencies": {
33
- "ilha": "0.6.0",
33
+ "ilha": "0.6.1",
34
34
  "rou3": "0.8.1"
35
35
  },
36
36
  "devDependencies": {