vike-lite-react 1.0.11 → 1.0.13

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.
@@ -2,16 +2,8 @@ import { t as PageContextProvider } from "../../PageContextProvider-DfE3nMiU.mjs
2
2
  import { Component, useCallback, useEffect, useMemo, useRef, useState } from "react";
3
3
  import { createRoot, hydrateRoot } from "react-dom/client";
4
4
  import { matchRoute } from "vike-lite/__internal/shared";
5
- import { createLinkClickHandler, createLinkPrefetchHandler, finalizeNavigation } from "vike-lite/__internal/client";
5
+ import { buildPageContextJsonUrl, createLinkClickHandler, createLinkPrefetchHandler, createRoutePrefetcher, fetchPageContextJson, finalizeNavigation, loadViewModules, stripBase, tryRecoverFromStaleModuleGraph } from "vike-lite/__internal/client";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
- //#region src/__internal/shared/stripBase.ts
8
- function stripBase(pathname) {
9
- const { BASE_URL } = import.meta.env;
10
- if (BASE_URL === "/" || !pathname.startsWith(BASE_URL)) return pathname;
11
- const stripped = pathname.slice(BASE_URL.length);
12
- return stripped.startsWith("/") ? stripped : "/" + stripped;
13
- }
14
- //#endregion
15
7
  //#region src/__internal/client/onRenderClient.tsx
16
8
  var RootErrorBoundary = class extends Component {
17
9
  static getDerivedStateFromError(error) {
@@ -43,21 +35,7 @@ function RouterApp(props) {
43
35
  setCurrentUrl(url.href);
44
36
  setCurrentPathname(stripBase(url.pathname));
45
37
  });
46
- const prefetchedModules = /* @__PURE__ */ new Set();
47
- function prefetchRoute(route) {
48
- const modules = [
49
- [route.page, route.Page],
50
- [route.layout, route.Layout],
51
- [route.head, route.Head]
52
- ];
53
- for (const [key, loader] of modules) {
54
- if (!key || !loader || prefetchedModules.has(key)) continue;
55
- prefetchedModules.add(key);
56
- loader().catch(() => {
57
- prefetchedModules.delete(key);
58
- });
59
- }
60
- }
38
+ const prefetchRoute = createRoutePrefetcher();
61
39
  const handleLinkPrefetch = createLinkPrefetchHandler((url) => {
62
40
  const matched = matchRoute(stripBase(url.pathname), props.routes);
63
41
  if (matched) prefetchRoute(matched.route);
@@ -108,11 +86,7 @@ function RouterApp(props) {
108
86
  const matched = matchedRoute;
109
87
  const renderErrorPage = async (is404, message) => {
110
88
  if (!props.errorRoute) return;
111
- const [ErrorPageMod, ErrorLayoutMod, ErrorHeadMod] = await Promise.all([
112
- props.errorRoute.Page(),
113
- props.errorRoute.Layout?.() ?? null,
114
- props.errorRoute.Head?.() ?? null
115
- ]);
89
+ const errorView = await loadViewModules(props.errorRoute);
116
90
  if (signal.aborted) return;
117
91
  setPageContext(() => ({
118
92
  ...pageContext,
@@ -125,11 +99,7 @@ function RouterApp(props) {
125
99
  isClientSide: true,
126
100
  isHydration: false
127
101
  }));
128
- setView({
129
- Page: ErrorPageMod.Page ?? ErrorPageMod.default,
130
- Layout: ErrorLayoutMod?.Layout ?? ErrorLayoutMod?.default ?? null,
131
- Head: ErrorHeadMod?.Head ?? ErrorHeadMod?.default ?? null
132
- });
102
+ setView(errorView);
133
103
  document.title = is404 ? "Not Found" : "Server Error";
134
104
  finalizeNavigation(shouldScrollToTop.current);
135
105
  };
@@ -140,19 +110,11 @@ function RouterApp(props) {
140
110
  const { route, routeParams } = matched;
141
111
  try {
142
112
  const urlObj = new URL(urlFull);
143
- const jsonTarget = pathname === "/" ? "/index" : pathname;
144
- const { BASE_URL } = import.meta.env;
145
- const jsonUrl = `${BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL}${jsonTarget}.pageContext.json${urlObj.search}`;
146
- let ctx = null;
147
- if (route.data || route.title) {
148
- const res = await fetch(jsonUrl, {
149
- signal,
150
- cache: isReload ? "no-cache" : "default"
151
- });
152
- const contentType = res.headers.get("content-type") ?? "";
153
- if (!contentType.includes("application/json")) throw new Error(`Expected JSON but got "${contentType}" for ${jsonUrl}. Check your proxy/CDN configuration.`);
154
- ctx = await res.json();
155
- }
113
+ const jsonUrl = buildPageContextJsonUrl(pathname, urlObj.search);
114
+ const ctx = route.data || route.title ? await fetchPageContextJson(jsonUrl, {
115
+ signal,
116
+ cache: isReload ? "no-cache" : "default"
117
+ }) : null;
156
118
  if (signal.aborted) return;
157
119
  if (ctx?._redirect) {
158
120
  const urlObjRedirect = new URL(ctx._redirect, globalThis.location.origin);
@@ -167,11 +129,7 @@ function RouterApp(props) {
167
129
  return;
168
130
  }
169
131
  if (ctx && (ctx.is404 || ctx.is500 || ctx.isError)) return renderErrorPage(ctx.is404, ctx.reason || "Server Error");
170
- const [PageMod, LayoutMod, HeadMod] = await Promise.all([
171
- route.Page(),
172
- route.Layout?.() ?? null,
173
- route.Head?.() ?? null
174
- ]);
132
+ const newView = await loadViewModules(route);
175
133
  if (signal.aborted) return;
176
134
  setPageContext(() => ({
177
135
  routeParams,
@@ -184,11 +142,7 @@ function RouterApp(props) {
184
142
  isClientSide: true,
185
143
  isHydration: false
186
144
  }));
187
- setView({
188
- Page: PageMod.Page ?? PageMod.default,
189
- Layout: LayoutMod?.Layout ?? LayoutMod?.default ?? null,
190
- Head: HeadMod?.Head ?? HeadMod?.default ?? null
191
- });
145
+ setView(newView);
192
146
  if (ctx?.title) document.title = ctx.title;
193
147
  requestAnimationFrame(() => {
194
148
  if (globalThis.location.hash) return;
@@ -198,16 +152,7 @@ function RouterApp(props) {
198
152
  } catch (error) {
199
153
  if (error.name === "AbortError") return;
200
154
  const message = error.message || "";
201
- if (/dynamically imported module|importing a module script failed/i.test(message)) {
202
- const GUARD_KEY = "vike-lite:reload-guard";
203
- const last = Number(sessionStorage.getItem(GUARD_KEY) ?? 0);
204
- if (Date.now() - last > 1e4) {
205
- sessionStorage.setItem(GUARD_KEY, String(Date.now()));
206
- console.warn("App update detected, forcing reload…");
207
- globalThis.location.assign(urlFull);
208
- return;
209
- }
210
- }
155
+ if (tryRecoverFromStaleModuleGraph(message, urlFull)) return;
211
156
  console.error("Router Error:", error);
212
157
  renderErrorPage(false, message);
213
158
  } finally {
@@ -250,18 +195,7 @@ async function onRenderClient(clientOptions) {
250
195
  };
251
196
  if (isHydration) {
252
197
  const matched = matchRoute(initialContext.urlPathname ?? globalThis.location.pathname, clientOptions.routes);
253
- if (matched) {
254
- const [PageMod, LayoutMod, HeadMod] = await Promise.all([
255
- matched.route.Page(),
256
- matched.route.Layout?.() ?? null,
257
- matched.route.Head?.() ?? null
258
- ]);
259
- initialView = {
260
- Page: PageMod.Page ?? PageMod.default,
261
- Layout: LayoutMod?.Layout ?? LayoutMod?.default ?? null,
262
- Head: HeadMod?.Head ?? HeadMod?.default ?? null
263
- };
264
- }
198
+ if (matched) initialView = await loadViewModules(matched.route);
265
199
  }
266
200
  const app = /* @__PURE__ */ jsx(RouterApp, {
267
201
  ...clientOptions,
package/dist/vite.mjs CHANGED
@@ -1,22 +1,11 @@
1
1
  import react from "@vitejs/plugin-react";
2
+ import { createFrameworkAdapterPlugin } from "vike-lite/__internal/vite";
2
3
  //#region src/vite.ts
3
4
  function vikeLiteReact({ hydration = true, react: reactOptions } = {}) {
4
- const virtualClientId = "virtual:vike-lite/client";
5
- const virtualServerId = "virtual:vike-lite/server";
6
- const resolvedVirtualClientId = "\0virtual:vike-lite/client";
7
- const resolvedVirtualServerId = "\0virtual:vike-lite/server";
8
- const adapter = {
9
- name: "vike-lite-react",
10
- enforce: "pre",
11
- resolveId(id) {
12
- if (id === virtualClientId) return resolvedVirtualClientId;
13
- if (id === virtualServerId) return resolvedVirtualServerId;
14
- },
15
- load(id) {
16
- if (id === resolvedVirtualClientId) return `export const onRenderClient=async(options)=>(await import("vike-lite-react/__internal/client/onRenderClient")).onRenderClient({...options,hydration:${hydration}});`;
17
- if (id === resolvedVirtualServerId) return `import { onRenderHtml as _onRenderHtml } from 'vike-lite-react/__internal/server/onRenderHtml';export const onRenderHtml = (ctx) => _onRenderHtml({ ...ctx, hydration: ${hydration} });`;
18
- }
19
- };
5
+ const adapter = createFrameworkAdapterPlugin({
6
+ packageName: "vike-lite-react",
7
+ hydration
8
+ });
20
9
  return [...react(reactOptions), adapter];
21
10
  }
22
11
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike-lite-react",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -63,7 +63,7 @@
63
63
  "react": "^19.2.7",
64
64
  "react-dom": "^19.2.7",
65
65
  "tsdown": "^0.22.9",
66
- "vike-lite": "1.15.8",
66
+ "vike-lite": "1.15.11",
67
67
  "vite": "^8.1.5"
68
68
  },
69
69
  "peerDependencies": {