vike-lite-react 1.0.12 → 1.0.14

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.
@@ -1,8 +1,8 @@
1
1
  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
- import { BASE_URL, matchRoute, stripBase } from "vike-lite/__internal/shared";
5
- import { createLinkClickHandler, createLinkPrefetchHandler, finalizeNavigation } from "vike-lite/__internal/client";
4
+ import { matchRoute, stripBase } from "vike-lite/__internal/shared";
5
+ import { buildPageContextJsonUrl, createLinkClickHandler, createLinkPrefetchHandler, createRoutePrefetcher, fetchPageContextJson, finalizeNavigation, loadViewModules, tryRecoverFromStaleModuleGraph } from "vike-lite/__internal/client";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/__internal/client/onRenderClient.tsx
8
8
  var RootErrorBoundary = class extends Component {
@@ -35,21 +35,7 @@ function RouterApp(props) {
35
35
  setCurrentUrl(url.href);
36
36
  setCurrentPathname(stripBase(url.pathname));
37
37
  });
38
- const prefetchedModules = /* @__PURE__ */ new Set();
39
- function prefetchRoute(route) {
40
- const modules = [
41
- [route.page, route.Page],
42
- [route.layout, route.Layout],
43
- [route.head, route.Head]
44
- ];
45
- for (const [key, loader] of modules) {
46
- if (!key || !loader || prefetchedModules.has(key)) continue;
47
- prefetchedModules.add(key);
48
- loader().catch(() => {
49
- prefetchedModules.delete(key);
50
- });
51
- }
52
- }
38
+ const prefetchRoute = createRoutePrefetcher();
53
39
  const handleLinkPrefetch = createLinkPrefetchHandler((url) => {
54
40
  const matched = matchRoute(stripBase(url.pathname), props.routes);
55
41
  if (matched) prefetchRoute(matched.route);
@@ -100,11 +86,7 @@ function RouterApp(props) {
100
86
  const matched = matchedRoute;
101
87
  const renderErrorPage = async (is404, message) => {
102
88
  if (!props.errorRoute) return;
103
- const [ErrorPageMod, ErrorLayoutMod, ErrorHeadMod] = await Promise.all([
104
- props.errorRoute.Page(),
105
- props.errorRoute.Layout?.() ?? null,
106
- props.errorRoute.Head?.() ?? null
107
- ]);
89
+ const errorView = await loadViewModules(props.errorRoute);
108
90
  if (signal.aborted) return;
109
91
  setPageContext(() => ({
110
92
  ...pageContext,
@@ -117,13 +99,9 @@ function RouterApp(props) {
117
99
  isClientSide: true,
118
100
  isHydration: false
119
101
  }));
120
- setView({
121
- Page: ErrorPageMod.Page ?? ErrorPageMod.default,
122
- Layout: ErrorLayoutMod?.Layout ?? ErrorLayoutMod?.default ?? null,
123
- Head: ErrorHeadMod?.Head ?? ErrorHeadMod?.default ?? null
124
- });
102
+ setView(errorView);
125
103
  document.title = is404 ? "Not Found" : "Server Error";
126
- finalizeNavigation(shouldScrollToTop.current);
104
+ finalizeNavigation(shouldScrollToTop, "current");
127
105
  };
128
106
  const loadRoute = async () => {
129
107
  const contextOverride = pendingContextOverride.current;
@@ -132,17 +110,11 @@ function RouterApp(props) {
132
110
  const { route, routeParams } = matched;
133
111
  try {
134
112
  const urlObj = new URL(urlFull);
135
- const jsonUrl = `${BASE_URL}${pathname === "/" ? "/index" : pathname}.pageContext.json${urlObj.search}`;
136
- let ctx = null;
137
- if (route.data || route.title) {
138
- const res = await fetch(jsonUrl, {
139
- signal,
140
- cache: isReload ? "no-cache" : "default"
141
- });
142
- const contentType = res.headers.get("content-type") ?? "";
143
- if (!contentType.includes("application/json")) throw new Error(`Expected JSON but got "${contentType}" for ${jsonUrl}. Check your proxy/CDN configuration.`);
144
- ctx = await res.json();
145
- }
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;
146
118
  if (signal.aborted) return;
147
119
  if (ctx?._redirect) {
148
120
  const urlObjRedirect = new URL(ctx._redirect, globalThis.location.origin);
@@ -157,11 +129,7 @@ function RouterApp(props) {
157
129
  return;
158
130
  }
159
131
  if (ctx && (ctx.is404 || ctx.is500 || ctx.isError)) return renderErrorPage(ctx.is404, ctx.reason || "Server Error");
160
- const [PageMod, LayoutMod, HeadMod] = await Promise.all([
161
- route.Page(),
162
- route.Layout?.() ?? null,
163
- route.Head?.() ?? null
164
- ]);
132
+ const newView = await loadViewModules(route);
165
133
  if (signal.aborted) return;
166
134
  setPageContext(() => ({
167
135
  routeParams,
@@ -174,30 +142,17 @@ function RouterApp(props) {
174
142
  isClientSide: true,
175
143
  isHydration: false
176
144
  }));
177
- setView({
178
- Page: PageMod.Page ?? PageMod.default,
179
- Layout: LayoutMod?.Layout ?? LayoutMod?.default ?? null,
180
- Head: HeadMod?.Head ?? HeadMod?.default ?? null
181
- });
145
+ setView(newView);
182
146
  if (ctx?.title) document.title = ctx.title;
183
147
  requestAnimationFrame(() => {
184
148
  if (globalThis.location.hash) return;
185
149
  document.querySelector("#root")?.focus({ preventScroll: true });
186
150
  });
187
- finalizeNavigation(shouldScrollToTop.current);
151
+ finalizeNavigation(shouldScrollToTop, "current");
188
152
  } catch (error) {
189
153
  if (error.name === "AbortError") return;
190
154
  const message = error.message || "";
191
- if (/dynamically imported module|importing a module script failed/i.test(message)) {
192
- const GUARD_KEY = "vike-lite:reload-guard";
193
- const last = Number(sessionStorage.getItem(GUARD_KEY) ?? 0);
194
- if (Date.now() - last > 1e4) {
195
- sessionStorage.setItem(GUARD_KEY, String(Date.now()));
196
- console.warn("App update detected, forcing reload…");
197
- globalThis.location.assign(urlFull);
198
- return;
199
- }
200
- }
155
+ if (tryRecoverFromStaleModuleGraph(message, urlFull)) return;
201
156
  console.error("Router Error:", error);
202
157
  renderErrorPage(false, message);
203
158
  } finally {
@@ -240,18 +195,7 @@ async function onRenderClient(clientOptions) {
240
195
  };
241
196
  if (isHydration) {
242
197
  const matched = matchRoute(initialContext.urlPathname ?? globalThis.location.pathname, clientOptions.routes);
243
- if (matched) {
244
- const [PageMod, LayoutMod, HeadMod] = await Promise.all([
245
- matched.route.Page(),
246
- matched.route.Layout?.() ?? null,
247
- matched.route.Head?.() ?? null
248
- ]);
249
- initialView = {
250
- Page: PageMod.Page ?? PageMod.default,
251
- Layout: LayoutMod?.Layout ?? LayoutMod?.default ?? null,
252
- Head: HeadMod?.Head ?? HeadMod?.default ?? null
253
- };
254
- }
198
+ if (matched) initialView = await loadViewModules(matched.route);
255
199
  }
256
200
  const app = /* @__PURE__ */ jsx(RouterApp, {
257
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.12",
3
+ "version": "1.0.14",
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.9",
66
+ "vike-lite": "1.15.12",
67
67
  "vite": "^8.1.5"
68
68
  },
69
69
  "peerDependencies": {