olova 2.0.55 → 2.0.56
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 +28 -288
- package/dist/chunk-23UAGQ6N.js +2208 -0
- package/dist/chunk-23UAGQ6N.js.map +1 -0
- package/dist/chunk-D7SIC5TC.js +367 -0
- package/dist/chunk-D7SIC5TC.js.map +1 -0
- package/dist/entry-server.cjs +2341 -0
- package/dist/entry-server.cjs.map +1 -0
- package/dist/entry-server.js +114 -0
- package/dist/entry-server.js.map +1 -0
- package/dist/entry-worker.cjs +2354 -0
- package/dist/entry-worker.cjs.map +1 -0
- package/dist/entry-worker.js +126 -0
- package/dist/entry-worker.js.map +1 -0
- package/dist/main.cjs +18 -0
- package/dist/main.cjs.map +1 -0
- package/dist/main.js +16 -0
- package/dist/main.js.map +1 -0
- package/dist/olova.cjs +1684 -0
- package/dist/olova.cjs.map +1 -0
- package/dist/olova.d.cts +72 -0
- package/dist/olova.d.ts +72 -0
- package/dist/olova.js +1325 -0
- package/dist/olova.js.map +1 -0
- package/dist/performance.cjs +386 -0
- package/dist/performance.cjs.map +1 -0
- package/dist/performance.js +3 -0
- package/dist/performance.js.map +1 -0
- package/dist/router.cjs +646 -0
- package/dist/router.cjs.map +1 -0
- package/dist/router.d.cts +113 -0
- package/dist/router.d.ts +113 -0
- package/dist/router.js +632 -0
- package/dist/router.js.map +1 -0
- package/main.tsx +76 -0
- package/olova.ts +619 -0
- package/package.json +42 -61
- package/src/entry-server.tsx +165 -0
- package/src/entry-worker.tsx +201 -0
- package/src/generator/index.ts +409 -0
- package/src/hydration/flight.ts +320 -0
- package/src/hydration/index.ts +12 -0
- package/src/hydration/types.ts +225 -0
- package/src/logger.ts +182 -0
- package/src/main.tsx +24 -0
- package/src/performance.ts +488 -0
- package/src/plugin/index.ts +204 -0
- package/src/router/ErrorBoundary.tsx +145 -0
- package/src/router/Link.tsx +117 -0
- package/src/router/OlovaRouter.tsx +354 -0
- package/src/router/Outlet.tsx +8 -0
- package/src/router/context.ts +117 -0
- package/src/router/index.ts +29 -0
- package/src/router/matching.ts +63 -0
- package/src/router/router.tsx +23 -0
- package/src/router/search-params.ts +29 -0
- package/src/scanner/index.ts +116 -0
- package/src/types/index.ts +191 -0
- package/src/utils/export.ts +85 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/naming.ts +54 -0
- package/src/utils/path.ts +45 -0
- package/tsup.config.ts +35 -0
- package/CHANGELOG.md +0 -31
- package/LICENSE +0 -21
- package/dist/index.cjs +0 -883
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -138
- package/dist/index.d.ts +0 -138
- package/dist/index.js +0 -832
- package/dist/index.js.map +0 -1
- package/dist/plugin.cjs +0 -927
- package/dist/plugin.cjs.map +0 -1
- package/dist/plugin.d.cts +0 -18
- package/dist/plugin.d.ts +0 -18
- package/dist/plugin.js +0 -894
- package/dist/plugin.js.map +0 -1
- package/dist/ssg.cjs +0 -637
- package/dist/ssg.cjs.map +0 -1
- package/dist/ssg.d.cts +0 -191
- package/dist/ssg.d.ts +0 -191
- package/dist/ssg.js +0 -585
- package/dist/ssg.js.map +0 -1
- package/dist/types-BT6YsBGO.d.cts +0 -143
- package/dist/types-BT6YsBGO.d.ts +0 -143
package/dist/index.cjs
DELETED
|
@@ -1,883 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var src_exports = {};
|
|
22
|
-
__export(src_exports, {
|
|
23
|
-
DefaultErrorComponent: () => DefaultErrorComponent,
|
|
24
|
-
DefaultLoadingComponent: () => DefaultLoadingComponent,
|
|
25
|
-
DefaultNotFoundComponent: () => DefaultNotFoundComponent,
|
|
26
|
-
Link: () => Link,
|
|
27
|
-
MetadataHead: () => MetadataHead,
|
|
28
|
-
MetadataProvider: () => MetadataProvider,
|
|
29
|
-
NavLink: () => NavLink,
|
|
30
|
-
NotFoundBoundary: () => NotFoundBoundary,
|
|
31
|
-
NotFoundError: () => NotFoundError,
|
|
32
|
-
OlovaRouter: () => OlovaRouter,
|
|
33
|
-
RouteErrorBoundary: () => RouteErrorBoundary,
|
|
34
|
-
RouteLoadingBoundary: () => RouteLoadingBoundary,
|
|
35
|
-
Skeleton: () => Skeleton,
|
|
36
|
-
SkeletonCard: () => SkeletonCard,
|
|
37
|
-
SkeletonText: () => SkeletonText,
|
|
38
|
-
generateMetadataHtml: () => generateMetadataHtml,
|
|
39
|
-
notFound: () => notFound,
|
|
40
|
-
setSSRContext: () => setSSRContext,
|
|
41
|
-
useMetadata: () => useMetadata,
|
|
42
|
-
useOlovaRouter: () => useOlovaRouter,
|
|
43
|
-
usePageMetadata: () => usePageMetadata,
|
|
44
|
-
useParams: () => useParams,
|
|
45
|
-
usePathname: () => usePathname,
|
|
46
|
-
useRouter: () => useRouter,
|
|
47
|
-
useSearchParams: () => useSearchParams
|
|
48
|
-
});
|
|
49
|
-
module.exports = __toCommonJS(src_exports);
|
|
50
|
-
|
|
51
|
-
// src/router.tsx
|
|
52
|
-
var import_react5 = require("react");
|
|
53
|
-
|
|
54
|
-
// src/context.tsx
|
|
55
|
-
var import_react = require("react");
|
|
56
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
57
|
-
var OlovaRouterContext = (0, import_react.createContext)(null);
|
|
58
|
-
var isBrowser = typeof window !== "undefined";
|
|
59
|
-
var ssrContextValue = {
|
|
60
|
-
pathname: "/",
|
|
61
|
-
params: {},
|
|
62
|
-
searchParams: new URLSearchParams(),
|
|
63
|
-
navigate: () => {
|
|
64
|
-
},
|
|
65
|
-
replace: () => {
|
|
66
|
-
},
|
|
67
|
-
back: () => {
|
|
68
|
-
},
|
|
69
|
-
forward: () => {
|
|
70
|
-
},
|
|
71
|
-
refresh: () => {
|
|
72
|
-
},
|
|
73
|
-
prefetch: () => {
|
|
74
|
-
},
|
|
75
|
-
isNavigating: false
|
|
76
|
-
};
|
|
77
|
-
function setSSRContext(pathname, params = {}) {
|
|
78
|
-
ssrContextValue = {
|
|
79
|
-
pathname,
|
|
80
|
-
params,
|
|
81
|
-
searchParams: new URLSearchParams(),
|
|
82
|
-
navigate: () => {
|
|
83
|
-
},
|
|
84
|
-
replace: () => {
|
|
85
|
-
},
|
|
86
|
-
back: () => {
|
|
87
|
-
},
|
|
88
|
-
forward: () => {
|
|
89
|
-
},
|
|
90
|
-
refresh: () => {
|
|
91
|
-
},
|
|
92
|
-
prefetch: () => {
|
|
93
|
-
},
|
|
94
|
-
isNavigating: false
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
function useOlovaRouter() {
|
|
98
|
-
const context = (0, import_react.useContext)(OlovaRouterContext);
|
|
99
|
-
if (!context) {
|
|
100
|
-
if (!isBrowser) {
|
|
101
|
-
return ssrContextValue;
|
|
102
|
-
}
|
|
103
|
-
throw new Error("useOlovaRouter must be used within an OlovaRouter");
|
|
104
|
-
}
|
|
105
|
-
return context;
|
|
106
|
-
}
|
|
107
|
-
function usePathname() {
|
|
108
|
-
return useOlovaRouter().pathname;
|
|
109
|
-
}
|
|
110
|
-
function useParams() {
|
|
111
|
-
return useOlovaRouter().params;
|
|
112
|
-
}
|
|
113
|
-
function useSearchParams() {
|
|
114
|
-
return useOlovaRouter().searchParams;
|
|
115
|
-
}
|
|
116
|
-
function useRouter() {
|
|
117
|
-
const { navigate, replace, back, forward, refresh, prefetch, isNavigating } = useOlovaRouter();
|
|
118
|
-
return {
|
|
119
|
-
push: navigate,
|
|
120
|
-
replace,
|
|
121
|
-
back,
|
|
122
|
-
forward,
|
|
123
|
-
refresh,
|
|
124
|
-
prefetch,
|
|
125
|
-
isNavigating
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
function OlovaRouterProvider({ children, basePath = "" }) {
|
|
129
|
-
const [pathname, setPathname] = (0, import_react.useState)(() => {
|
|
130
|
-
const path = window.location.pathname;
|
|
131
|
-
return basePath ? path.replace(new RegExp(`^${basePath}`), "") || "/" : path;
|
|
132
|
-
});
|
|
133
|
-
const [searchParams, setSearchParams] = (0, import_react.useState)(() => new URLSearchParams(window.location.search));
|
|
134
|
-
const [params, setParams] = (0, import_react.useState)({});
|
|
135
|
-
const [isPending, startTransition] = (0, import_react.useTransition)();
|
|
136
|
-
(0, import_react.useEffect)(() => {
|
|
137
|
-
const handlePopState = () => {
|
|
138
|
-
startTransition(() => {
|
|
139
|
-
const path = window.location.pathname;
|
|
140
|
-
setPathname(basePath ? path.replace(new RegExp(`^${basePath}`), "") || "/" : path);
|
|
141
|
-
setSearchParams(new URLSearchParams(window.location.search));
|
|
142
|
-
});
|
|
143
|
-
};
|
|
144
|
-
window.addEventListener("popstate", handlePopState);
|
|
145
|
-
return () => window.removeEventListener("popstate", handlePopState);
|
|
146
|
-
}, [basePath]);
|
|
147
|
-
const navigate = (0, import_react.useCallback)((to, options = {}) => {
|
|
148
|
-
const url = new URL(to, window.location.origin);
|
|
149
|
-
const fullPath = basePath + url.pathname;
|
|
150
|
-
startTransition(() => {
|
|
151
|
-
if (options.replace) {
|
|
152
|
-
window.history.replaceState(null, "", fullPath + url.search);
|
|
153
|
-
} else {
|
|
154
|
-
window.history.pushState(null, "", fullPath + url.search);
|
|
155
|
-
}
|
|
156
|
-
setPathname(url.pathname);
|
|
157
|
-
setSearchParams(new URLSearchParams(url.search));
|
|
158
|
-
if (options.scroll !== false) {
|
|
159
|
-
window.scrollTo(0, 0);
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
}, [basePath]);
|
|
163
|
-
const replace = (0, import_react.useCallback)((to, options = {}) => {
|
|
164
|
-
navigate(to, { ...options, replace: true });
|
|
165
|
-
}, [navigate]);
|
|
166
|
-
const back = (0, import_react.useCallback)(() => {
|
|
167
|
-
window.history.back();
|
|
168
|
-
}, []);
|
|
169
|
-
const forward = (0, import_react.useCallback)(() => {
|
|
170
|
-
window.history.forward();
|
|
171
|
-
}, []);
|
|
172
|
-
const refresh = (0, import_react.useCallback)(() => {
|
|
173
|
-
startTransition(() => {
|
|
174
|
-
setPathname((prev) => prev);
|
|
175
|
-
});
|
|
176
|
-
}, []);
|
|
177
|
-
const prefetch = (0, import_react.useCallback)((href) => {
|
|
178
|
-
console.log("[Olova] Prefetching:", href);
|
|
179
|
-
}, []);
|
|
180
|
-
const updateParams = (0, import_react.useCallback)((newParams) => {
|
|
181
|
-
setParams(newParams);
|
|
182
|
-
}, []);
|
|
183
|
-
const contextValue = {
|
|
184
|
-
pathname,
|
|
185
|
-
params,
|
|
186
|
-
searchParams,
|
|
187
|
-
navigate,
|
|
188
|
-
replace,
|
|
189
|
-
back,
|
|
190
|
-
forward,
|
|
191
|
-
refresh,
|
|
192
|
-
prefetch,
|
|
193
|
-
isNavigating: isPending
|
|
194
|
-
};
|
|
195
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OlovaRouterContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OlovaParamsUpdater, { updateParams, children }) });
|
|
196
|
-
}
|
|
197
|
-
var ParamsUpdaterContext = (0, import_react.createContext)(null);
|
|
198
|
-
function OlovaParamsUpdater({
|
|
199
|
-
children,
|
|
200
|
-
updateParams
|
|
201
|
-
}) {
|
|
202
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ParamsUpdaterContext.Provider, { value: updateParams, children });
|
|
203
|
-
}
|
|
204
|
-
function useParamsUpdater() {
|
|
205
|
-
return (0, import_react.useContext)(ParamsUpdaterContext);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// src/components/ErrorBoundary.tsx
|
|
209
|
-
var import_react2 = require("react");
|
|
210
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
211
|
-
var RouteErrorBoundary = class extends import_react2.Component {
|
|
212
|
-
constructor(props) {
|
|
213
|
-
super(props);
|
|
214
|
-
this.reset = () => {
|
|
215
|
-
this.setState({ hasError: false, error: null });
|
|
216
|
-
};
|
|
217
|
-
this.state = { hasError: false, error: null };
|
|
218
|
-
}
|
|
219
|
-
static getDerivedStateFromError(error) {
|
|
220
|
-
return { hasError: true, error };
|
|
221
|
-
}
|
|
222
|
-
componentDidCatch(error, errorInfo) {
|
|
223
|
-
console.error("[Olova] Route error:", error, errorInfo);
|
|
224
|
-
this.props.onError?.(error, errorInfo);
|
|
225
|
-
}
|
|
226
|
-
render() {
|
|
227
|
-
if (this.state.hasError && this.state.error) {
|
|
228
|
-
const FallbackComponent = this.props.fallback;
|
|
229
|
-
if (FallbackComponent) {
|
|
230
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FallbackComponent, { error: this.state.error, reset: this.reset });
|
|
231
|
-
}
|
|
232
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex min-h-[400px] flex-col items-center justify-center p-8", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rounded-lg border border-destructive/20 bg-destructive/5 p-6 text-center", children: [
|
|
233
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "mb-2 text-xl font-semibold text-destructive", children: "Something went wrong!" }),
|
|
234
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mb-4 text-sm text-muted-foreground", children: this.state.error.message }),
|
|
235
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
236
|
-
"button",
|
|
237
|
-
{
|
|
238
|
-
onClick: this.reset,
|
|
239
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
|
|
240
|
-
children: "Try again"
|
|
241
|
-
}
|
|
242
|
-
)
|
|
243
|
-
] }) });
|
|
244
|
-
}
|
|
245
|
-
return this.props.children;
|
|
246
|
-
}
|
|
247
|
-
};
|
|
248
|
-
function DefaultErrorComponent({ error, reset }) {
|
|
249
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex min-h-[400px] flex-col items-center justify-center p-8", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-md rounded-lg border border-destructive/20 bg-destructive/5 p-6 text-center", children: [
|
|
250
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
251
|
-
"svg",
|
|
252
|
-
{
|
|
253
|
-
className: "h-6 w-6 text-destructive",
|
|
254
|
-
fill: "none",
|
|
255
|
-
viewBox: "0 0 24 24",
|
|
256
|
-
stroke: "currentColor",
|
|
257
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
258
|
-
"path",
|
|
259
|
-
{
|
|
260
|
-
strokeLinecap: "round",
|
|
261
|
-
strokeLinejoin: "round",
|
|
262
|
-
strokeWidth: 2,
|
|
263
|
-
d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
|
|
264
|
-
}
|
|
265
|
-
)
|
|
266
|
-
}
|
|
267
|
-
) }),
|
|
268
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "mb-2 text-xl font-semibold text-foreground", children: "Something went wrong!" }),
|
|
269
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mb-4 text-sm text-muted-foreground", children: error.message }),
|
|
270
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
271
|
-
"button",
|
|
272
|
-
{
|
|
273
|
-
onClick: reset,
|
|
274
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90",
|
|
275
|
-
children: "Try again"
|
|
276
|
-
}
|
|
277
|
-
)
|
|
278
|
-
] }) });
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// src/components/Loading.tsx
|
|
282
|
-
var import_react3 = require("react");
|
|
283
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
284
|
-
function RouteLoadingBoundary({ children, fallback }) {
|
|
285
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react3.Suspense, { fallback: fallback || /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DefaultLoadingComponent, {}), children });
|
|
286
|
-
}
|
|
287
|
-
function DefaultLoadingComponent() {
|
|
288
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex min-h-[400px] flex-col items-center justify-center p-8", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
289
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative h-10 w-10", children: [
|
|
290
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute inset-0 animate-ping rounded-full bg-primary/20" }),
|
|
291
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute inset-0 animate-pulse rounded-full bg-primary/40" }),
|
|
292
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute inset-2 animate-spin rounded-full border-2 border-primary border-t-transparent" })
|
|
293
|
-
] }),
|
|
294
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-muted-foreground", children: "Loading..." })
|
|
295
|
-
] }) });
|
|
296
|
-
}
|
|
297
|
-
function Skeleton({ className = "" }) {
|
|
298
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
299
|
-
"div",
|
|
300
|
-
{
|
|
301
|
-
className: `animate-pulse rounded-md bg-muted ${className}`,
|
|
302
|
-
"aria-hidden": "true"
|
|
303
|
-
}
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
function SkeletonText({ lines = 3, className = "" }) {
|
|
307
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `space-y-2 ${className}`, children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
308
|
-
Skeleton,
|
|
309
|
-
{
|
|
310
|
-
className: `h-4 ${i === lines - 1 ? "w-3/4" : "w-full"}`
|
|
311
|
-
},
|
|
312
|
-
i
|
|
313
|
-
)) });
|
|
314
|
-
}
|
|
315
|
-
function SkeletonCard({ className = "" }) {
|
|
316
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `rounded-lg border bg-card p-6 ${className}`, children: [
|
|
317
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Skeleton, { className: "mb-4 h-6 w-1/2" }),
|
|
318
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SkeletonText, { lines: 3 })
|
|
319
|
-
] });
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// src/components/NotFound.tsx
|
|
323
|
-
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
324
|
-
function NotFoundBoundary({ children, fallback: Fallback, show404 }) {
|
|
325
|
-
if (show404) {
|
|
326
|
-
if (Fallback) {
|
|
327
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Fallback, {});
|
|
328
|
-
}
|
|
329
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DefaultNotFoundComponent, {});
|
|
330
|
-
}
|
|
331
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children });
|
|
332
|
-
}
|
|
333
|
-
function DefaultNotFoundComponent() {
|
|
334
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex min-h-[60vh] flex-col items-center justify-center p-8", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "text-center", children: [
|
|
335
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mb-2 text-8xl font-bold text-primary", children: "404" }),
|
|
336
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mb-4 text-2xl font-semibold text-foreground", children: "Page Not Found" }),
|
|
337
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mb-8 max-w-md text-muted-foreground", children: "The page you're looking for doesn't exist or has been moved." }),
|
|
338
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
339
|
-
"a",
|
|
340
|
-
{
|
|
341
|
-
href: "/",
|
|
342
|
-
className: "inline-flex items-center gap-2 rounded-md bg-primary px-6 py-3 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90",
|
|
343
|
-
children: [
|
|
344
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
345
|
-
"svg",
|
|
346
|
-
{
|
|
347
|
-
className: "h-4 w-4",
|
|
348
|
-
fill: "none",
|
|
349
|
-
viewBox: "0 0 24 24",
|
|
350
|
-
stroke: "currentColor",
|
|
351
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
352
|
-
"path",
|
|
353
|
-
{
|
|
354
|
-
strokeLinecap: "round",
|
|
355
|
-
strokeLinejoin: "round",
|
|
356
|
-
strokeWidth: 2,
|
|
357
|
-
d: "M10 19l-7-7m0 0l7-7m-7 7h18"
|
|
358
|
-
}
|
|
359
|
-
)
|
|
360
|
-
}
|
|
361
|
-
),
|
|
362
|
-
"Go back home"
|
|
363
|
-
]
|
|
364
|
-
}
|
|
365
|
-
)
|
|
366
|
-
] }) });
|
|
367
|
-
}
|
|
368
|
-
function notFound() {
|
|
369
|
-
throw new NotFoundError();
|
|
370
|
-
}
|
|
371
|
-
var NotFoundError = class extends Error {
|
|
372
|
-
constructor() {
|
|
373
|
-
super("NEXT_NOT_FOUND");
|
|
374
|
-
this.name = "NotFoundError";
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
// src/components/Metadata.tsx
|
|
379
|
-
var import_react4 = require("react");
|
|
380
|
-
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
381
|
-
var MetadataContext = (0, import_react4.createContext)(null);
|
|
382
|
-
function MetadataProvider({ children, rootMetadata }) {
|
|
383
|
-
const [metadata, setMetadataState] = (0, import_react4.useState)(rootMetadata || null);
|
|
384
|
-
const setMetadata = (0, import_react4.useCallback)((newMetadata) => {
|
|
385
|
-
setMetadataState(newMetadata);
|
|
386
|
-
}, []);
|
|
387
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MetadataContext.Provider, { value: { metadata, rootMetadata: rootMetadata || null, setMetadata }, children: [
|
|
388
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MetadataHead, { metadata, fallback: rootMetadata }),
|
|
389
|
-
children
|
|
390
|
-
] });
|
|
391
|
-
}
|
|
392
|
-
function useMetadata() {
|
|
393
|
-
const context = (0, import_react4.useContext)(MetadataContext);
|
|
394
|
-
if (!context) {
|
|
395
|
-
throw new Error("useMetadata must be used within a MetadataProvider");
|
|
396
|
-
}
|
|
397
|
-
return context;
|
|
398
|
-
}
|
|
399
|
-
function usePageMetadata(metadata) {
|
|
400
|
-
const context = (0, import_react4.useContext)(MetadataContext);
|
|
401
|
-
(0, import_react4.useEffect)(() => {
|
|
402
|
-
if (context && metadata) {
|
|
403
|
-
context.setMetadata(metadata);
|
|
404
|
-
}
|
|
405
|
-
return () => {
|
|
406
|
-
if (context) {
|
|
407
|
-
context.setMetadata(context.rootMetadata);
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
}, [metadata, context]);
|
|
411
|
-
}
|
|
412
|
-
function MetadataHead({ metadata, fallback }) {
|
|
413
|
-
(0, import_react4.useEffect)(() => {
|
|
414
|
-
const activeMetadata = metadata || fallback;
|
|
415
|
-
if (!activeMetadata) return;
|
|
416
|
-
if (activeMetadata.title) {
|
|
417
|
-
document.title = activeMetadata.title;
|
|
418
|
-
}
|
|
419
|
-
const addedMetas = [];
|
|
420
|
-
const setMeta = (name, content, property) => {
|
|
421
|
-
const attr = property ? "property" : "name";
|
|
422
|
-
let meta = document.querySelector(`meta[${attr}="${name}"]`);
|
|
423
|
-
if (!meta) {
|
|
424
|
-
meta = document.createElement("meta");
|
|
425
|
-
meta.setAttribute(attr, name);
|
|
426
|
-
document.head.appendChild(meta);
|
|
427
|
-
addedMetas.push(meta);
|
|
428
|
-
}
|
|
429
|
-
meta.content = content;
|
|
430
|
-
};
|
|
431
|
-
if (activeMetadata.description) {
|
|
432
|
-
setMeta("description", activeMetadata.description);
|
|
433
|
-
}
|
|
434
|
-
if (activeMetadata.keywords?.length) {
|
|
435
|
-
setMeta("keywords", activeMetadata.keywords.join(", "));
|
|
436
|
-
}
|
|
437
|
-
if (activeMetadata.authors?.length) {
|
|
438
|
-
setMeta("author", activeMetadata.authors.map((a) => a.name).join(", "));
|
|
439
|
-
}
|
|
440
|
-
if (activeMetadata.robots) {
|
|
441
|
-
setMeta("robots", activeMetadata.robots);
|
|
442
|
-
}
|
|
443
|
-
if (activeMetadata.openGraph) {
|
|
444
|
-
const og = activeMetadata.openGraph;
|
|
445
|
-
if (og.title) {
|
|
446
|
-
setMeta("og:title", og.title, true);
|
|
447
|
-
}
|
|
448
|
-
if (og.description) {
|
|
449
|
-
setMeta("og:description", og.description, true);
|
|
450
|
-
}
|
|
451
|
-
if (og.url) {
|
|
452
|
-
setMeta("og:url", og.url, true);
|
|
453
|
-
}
|
|
454
|
-
if (og.siteName) {
|
|
455
|
-
setMeta("og:site_name", og.siteName, true);
|
|
456
|
-
}
|
|
457
|
-
if (og.type) {
|
|
458
|
-
setMeta("og:type", og.type, true);
|
|
459
|
-
}
|
|
460
|
-
if (og.images?.length) {
|
|
461
|
-
const img = og.images[0];
|
|
462
|
-
setMeta("og:image", img.url, true);
|
|
463
|
-
if (img.width) setMeta("og:image:width", String(img.width), true);
|
|
464
|
-
if (img.height) setMeta("og:image:height", String(img.height), true);
|
|
465
|
-
if (img.alt) setMeta("og:image:alt", img.alt, true);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
if (activeMetadata.twitter) {
|
|
469
|
-
const tw = activeMetadata.twitter;
|
|
470
|
-
if (tw.card) {
|
|
471
|
-
setMeta("twitter:card", tw.card);
|
|
472
|
-
}
|
|
473
|
-
if (tw.title) {
|
|
474
|
-
setMeta("twitter:title", tw.title);
|
|
475
|
-
}
|
|
476
|
-
if (tw.description) {
|
|
477
|
-
setMeta("twitter:description", tw.description);
|
|
478
|
-
}
|
|
479
|
-
if (tw.site) {
|
|
480
|
-
setMeta("twitter:site", tw.site);
|
|
481
|
-
}
|
|
482
|
-
if (tw.creator) {
|
|
483
|
-
setMeta("twitter:creator", tw.creator);
|
|
484
|
-
}
|
|
485
|
-
if (tw.images?.length) {
|
|
486
|
-
setMeta("twitter:image", tw.images[0]);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
if (activeMetadata.canonical) {
|
|
490
|
-
let link = document.querySelector('link[rel="canonical"]');
|
|
491
|
-
if (!link) {
|
|
492
|
-
link = document.createElement("link");
|
|
493
|
-
link.rel = "canonical";
|
|
494
|
-
document.head.appendChild(link);
|
|
495
|
-
}
|
|
496
|
-
link.href = activeMetadata.canonical;
|
|
497
|
-
}
|
|
498
|
-
return () => {
|
|
499
|
-
addedMetas.forEach((meta) => {
|
|
500
|
-
if (meta.parentNode) {
|
|
501
|
-
meta.parentNode.removeChild(meta);
|
|
502
|
-
}
|
|
503
|
-
});
|
|
504
|
-
};
|
|
505
|
-
}, [metadata, fallback]);
|
|
506
|
-
return null;
|
|
507
|
-
}
|
|
508
|
-
function generateMetadataHtml(metadata) {
|
|
509
|
-
const tags = [];
|
|
510
|
-
if (metadata.title) {
|
|
511
|
-
tags.push(` <title>${escapeHtml(metadata.title)}</title>`);
|
|
512
|
-
}
|
|
513
|
-
if (metadata.description) {
|
|
514
|
-
tags.push(` <meta name="description" content="${escapeHtml(metadata.description)}" />`);
|
|
515
|
-
}
|
|
516
|
-
if (metadata.keywords?.length) {
|
|
517
|
-
tags.push(` <meta name="keywords" content="${escapeHtml(metadata.keywords.join(", "))}" />`);
|
|
518
|
-
}
|
|
519
|
-
if (metadata.authors?.length) {
|
|
520
|
-
tags.push(` <meta name="author" content="${escapeHtml(metadata.authors.map((a) => a.name).join(", "))}" />`);
|
|
521
|
-
}
|
|
522
|
-
if (metadata.robots) {
|
|
523
|
-
tags.push(` <meta name="robots" content="${escapeHtml(metadata.robots)}" />`);
|
|
524
|
-
}
|
|
525
|
-
if (metadata.openGraph) {
|
|
526
|
-
const og = metadata.openGraph;
|
|
527
|
-
if (og.title) tags.push(` <meta property="og:title" content="${escapeHtml(og.title)}" />`);
|
|
528
|
-
if (og.description) tags.push(` <meta property="og:description" content="${escapeHtml(og.description)}" />`);
|
|
529
|
-
if (og.url) tags.push(` <meta property="og:url" content="${escapeHtml(og.url)}" />`);
|
|
530
|
-
if (og.siteName) tags.push(` <meta property="og:site_name" content="${escapeHtml(og.siteName)}" />`);
|
|
531
|
-
if (og.type) tags.push(` <meta property="og:type" content="${escapeHtml(og.type)}" />`);
|
|
532
|
-
if (og.images?.length) {
|
|
533
|
-
const img = og.images[0];
|
|
534
|
-
tags.push(` <meta property="og:image" content="${escapeHtml(img.url)}" />`);
|
|
535
|
-
if (img.width) tags.push(` <meta property="og:image:width" content="${img.width}" />`);
|
|
536
|
-
if (img.height) tags.push(` <meta property="og:image:height" content="${img.height}" />`);
|
|
537
|
-
if (img.alt) tags.push(` <meta property="og:image:alt" content="${escapeHtml(img.alt)}" />`);
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
if (metadata.twitter) {
|
|
541
|
-
const tw = metadata.twitter;
|
|
542
|
-
if (tw.card) tags.push(` <meta name="twitter:card" content="${escapeHtml(tw.card)}" />`);
|
|
543
|
-
if (tw.title) tags.push(` <meta name="twitter:title" content="${escapeHtml(tw.title)}" />`);
|
|
544
|
-
if (tw.description) tags.push(` <meta name="twitter:description" content="${escapeHtml(tw.description)}" />`);
|
|
545
|
-
if (tw.site) tags.push(` <meta name="twitter:site" content="${escapeHtml(tw.site)}" />`);
|
|
546
|
-
if (tw.creator) tags.push(` <meta name="twitter:creator" content="${escapeHtml(tw.creator)}" />`);
|
|
547
|
-
if (tw.images?.length) tags.push(` <meta name="twitter:image" content="${escapeHtml(tw.images[0])}" />`);
|
|
548
|
-
}
|
|
549
|
-
if (metadata.canonical) {
|
|
550
|
-
tags.push(` <link rel="canonical" href="${escapeHtml(metadata.canonical)}" />`);
|
|
551
|
-
}
|
|
552
|
-
return tags.join("\n");
|
|
553
|
-
}
|
|
554
|
-
function escapeHtml(text) {
|
|
555
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
// src/router.tsx
|
|
559
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
560
|
-
function OlovaRouter({
|
|
561
|
-
routes,
|
|
562
|
-
basePath = "",
|
|
563
|
-
defaultLoading,
|
|
564
|
-
defaultNotFound,
|
|
565
|
-
defaultError,
|
|
566
|
-
rootMetadata,
|
|
567
|
-
routeMetadata
|
|
568
|
-
}) {
|
|
569
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(OlovaRouterProvider, { basePath, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
570
|
-
RouteRenderer,
|
|
571
|
-
{
|
|
572
|
-
routes,
|
|
573
|
-
defaultLoading,
|
|
574
|
-
defaultNotFound,
|
|
575
|
-
defaultError,
|
|
576
|
-
rootMetadata,
|
|
577
|
-
routeMetadata
|
|
578
|
-
}
|
|
579
|
-
) });
|
|
580
|
-
}
|
|
581
|
-
function RouteRenderer({
|
|
582
|
-
routes,
|
|
583
|
-
defaultLoading,
|
|
584
|
-
defaultNotFound,
|
|
585
|
-
defaultError,
|
|
586
|
-
rootMetadata,
|
|
587
|
-
routeMetadata
|
|
588
|
-
}) {
|
|
589
|
-
const pathname = usePathname();
|
|
590
|
-
const updateParams = useParamsUpdater();
|
|
591
|
-
const match = (0, import_react5.useMemo)(() => {
|
|
592
|
-
return matchRoute(routes, pathname);
|
|
593
|
-
}, [routes, pathname]);
|
|
594
|
-
(0, import_react5.useEffect)(() => {
|
|
595
|
-
if (updateParams && match) {
|
|
596
|
-
updateParams(match.params);
|
|
597
|
-
}
|
|
598
|
-
}, [match, updateParams]);
|
|
599
|
-
const currentMetadata = (0, import_react5.useMemo)(() => {
|
|
600
|
-
if (!routeMetadata) return null;
|
|
601
|
-
if (routeMetadata[pathname]) {
|
|
602
|
-
return routeMetadata[pathname];
|
|
603
|
-
}
|
|
604
|
-
return null;
|
|
605
|
-
}, [pathname, routeMetadata]);
|
|
606
|
-
if (!match) {
|
|
607
|
-
const NotFoundComponent = defaultNotFound || DefaultNotFoundComponent;
|
|
608
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
609
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MetadataHead, { metadata: currentMetadata, fallback: rootMetadata }),
|
|
610
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(NotFoundComponent, {})
|
|
611
|
-
] });
|
|
612
|
-
}
|
|
613
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
614
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MetadataHead, { metadata: currentMetadata, fallback: rootMetadata }),
|
|
615
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
616
|
-
LayoutRenderer,
|
|
617
|
-
{
|
|
618
|
-
match,
|
|
619
|
-
routes,
|
|
620
|
-
defaultLoading,
|
|
621
|
-
defaultError
|
|
622
|
-
}
|
|
623
|
-
)
|
|
624
|
-
] });
|
|
625
|
-
}
|
|
626
|
-
function LayoutRenderer({ match, routes, defaultLoading, defaultError }) {
|
|
627
|
-
const { route, params } = match;
|
|
628
|
-
const layoutChain = (0, import_react5.useMemo)(() => {
|
|
629
|
-
return findLayoutChain(routes, route);
|
|
630
|
-
}, [routes, route]);
|
|
631
|
-
const renderSlots = (currentRoute) => {
|
|
632
|
-
const slots = {};
|
|
633
|
-
if (currentRoute.slots) {
|
|
634
|
-
for (const [slotName, slotRoute] of Object.entries(currentRoute.slots)) {
|
|
635
|
-
if (slotRoute.component) {
|
|
636
|
-
const SlotComponent = slotRoute.component;
|
|
637
|
-
const SlotLoading = slotRoute.loading;
|
|
638
|
-
const SlotError = slotRoute.error || defaultError;
|
|
639
|
-
slots[slotName] = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RouteErrorBoundary, { fallback: SlotError, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RouteLoadingBoundary, { fallback: SlotLoading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SlotLoading, {}) : defaultLoading, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SlotComponent, { params, searchParams: {} }) }) }, slotName);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
return slots;
|
|
644
|
-
};
|
|
645
|
-
const renderLayouts = (index) => {
|
|
646
|
-
if (index >= layoutChain.length) {
|
|
647
|
-
if (!route.component) {
|
|
648
|
-
return null;
|
|
649
|
-
}
|
|
650
|
-
const PageComponent = route.component;
|
|
651
|
-
const LoadingComponent2 = route.loading;
|
|
652
|
-
const ErrorComponent2 = route.error || defaultError;
|
|
653
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RouteErrorBoundary, { fallback: ErrorComponent2, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RouteLoadingBoundary, { fallback: LoadingComponent2 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LoadingComponent2, {}) : defaultLoading, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PageComponent, { params, searchParams: {} }) }) });
|
|
654
|
-
}
|
|
655
|
-
const currentLayout = layoutChain[index];
|
|
656
|
-
if (!currentLayout.layout) {
|
|
657
|
-
return renderLayouts(index + 1);
|
|
658
|
-
}
|
|
659
|
-
const LayoutComponent = currentLayout.layout;
|
|
660
|
-
const LoadingComponent = currentLayout.loading;
|
|
661
|
-
const ErrorComponent = currentLayout.error || defaultError;
|
|
662
|
-
const slots = renderSlots(currentLayout);
|
|
663
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RouteErrorBoundary, { fallback: ErrorComponent, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RouteLoadingBoundary, { fallback: LoadingComponent ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LoadingComponent, {}) : defaultLoading, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LayoutComponent, { params, ...slots, children: renderLayouts(index + 1) }) }) });
|
|
664
|
-
};
|
|
665
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: renderLayouts(0) });
|
|
666
|
-
}
|
|
667
|
-
function matchRoute(routes, pathname) {
|
|
668
|
-
const segments = pathname.split("/").filter(Boolean);
|
|
669
|
-
function matchRecursive(routeList, segmentIndex, params) {
|
|
670
|
-
if (segmentIndex >= segments.length) {
|
|
671
|
-
for (const route of routeList) {
|
|
672
|
-
if (route.path === "" || route.path === "/") {
|
|
673
|
-
if (route.component) {
|
|
674
|
-
return {
|
|
675
|
-
route,
|
|
676
|
-
params,
|
|
677
|
-
pathname,
|
|
678
|
-
searchParams: new URLSearchParams(window.location.search)
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
return null;
|
|
684
|
-
}
|
|
685
|
-
const currentSegment = segments[segmentIndex];
|
|
686
|
-
for (const route of routeList) {
|
|
687
|
-
if (route.path.startsWith("(") && route.path.endsWith(")")) {
|
|
688
|
-
if (route.children.length > 0) {
|
|
689
|
-
const childMatch = matchRecursive(route.children, segmentIndex, params);
|
|
690
|
-
if (childMatch) return childMatch;
|
|
691
|
-
}
|
|
692
|
-
continue;
|
|
693
|
-
}
|
|
694
|
-
if (route.isCatchAll && route.paramName) {
|
|
695
|
-
const remainingSegments = segments.slice(segmentIndex);
|
|
696
|
-
const newParams = { ...params, [route.paramName]: remainingSegments.join("/") };
|
|
697
|
-
if (route.component) {
|
|
698
|
-
return {
|
|
699
|
-
route,
|
|
700
|
-
params: newParams,
|
|
701
|
-
pathname,
|
|
702
|
-
searchParams: new URLSearchParams(window.location.search)
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
if (route.isDynamic && route.paramName) {
|
|
707
|
-
const newParams = { ...params, [route.paramName]: currentSegment };
|
|
708
|
-
if (segmentIndex === segments.length - 1) {
|
|
709
|
-
if (route.component) {
|
|
710
|
-
return {
|
|
711
|
-
route,
|
|
712
|
-
params: newParams,
|
|
713
|
-
pathname,
|
|
714
|
-
searchParams: new URLSearchParams(window.location.search)
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
if (route.children.length > 0) {
|
|
719
|
-
const childMatch = matchRecursive(route.children, segmentIndex + 1, newParams);
|
|
720
|
-
if (childMatch) return childMatch;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
if (route.path === currentSegment) {
|
|
724
|
-
if (segmentIndex === segments.length - 1) {
|
|
725
|
-
if (route.component) {
|
|
726
|
-
return {
|
|
727
|
-
route,
|
|
728
|
-
params,
|
|
729
|
-
pathname,
|
|
730
|
-
searchParams: new URLSearchParams(window.location.search)
|
|
731
|
-
};
|
|
732
|
-
}
|
|
733
|
-
for (const child of route.children) {
|
|
734
|
-
if ((child.path === "" || child.path === "/") && child.component) {
|
|
735
|
-
return {
|
|
736
|
-
route: child,
|
|
737
|
-
params,
|
|
738
|
-
pathname,
|
|
739
|
-
searchParams: new URLSearchParams(window.location.search)
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
if (route.children.length > 0) {
|
|
745
|
-
const childMatch = matchRecursive(route.children, segmentIndex + 1, params);
|
|
746
|
-
if (childMatch) return childMatch;
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
return null;
|
|
751
|
-
}
|
|
752
|
-
if (pathname === "/" || pathname === "") {
|
|
753
|
-
for (const route of routes) {
|
|
754
|
-
if ((route.path === "" || route.path === "/") && route.component) {
|
|
755
|
-
return {
|
|
756
|
-
route,
|
|
757
|
-
params: {},
|
|
758
|
-
pathname: "/",
|
|
759
|
-
searchParams: new URLSearchParams(window.location.search)
|
|
760
|
-
};
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
return matchRecursive(routes, 0, {});
|
|
765
|
-
}
|
|
766
|
-
function findLayoutChain(routes, targetRoute) {
|
|
767
|
-
const chain = [];
|
|
768
|
-
function findRecursive(routeList, path) {
|
|
769
|
-
for (const route of routeList) {
|
|
770
|
-
const currentPath = [...path, route];
|
|
771
|
-
if (route.id === targetRoute.id) {
|
|
772
|
-
for (const r of currentPath) {
|
|
773
|
-
if (r.layout) {
|
|
774
|
-
chain.push(r);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
return true;
|
|
778
|
-
}
|
|
779
|
-
if (route.children.length > 0) {
|
|
780
|
-
if (findRecursive(route.children, currentPath)) {
|
|
781
|
-
return true;
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
return false;
|
|
786
|
-
}
|
|
787
|
-
findRecursive(routes, []);
|
|
788
|
-
return chain;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
// src/components/Link.tsx
|
|
792
|
-
var import_react6 = require("react");
|
|
793
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
794
|
-
var Link = (0, import_react6.forwardRef)(
|
|
795
|
-
({ href, replace = false, scroll = true, prefetch = true, children, onClick, ...props }, ref) => {
|
|
796
|
-
const router = useOlovaRouter();
|
|
797
|
-
const handleClick = (0, import_react6.useCallback)(
|
|
798
|
-
(e) => {
|
|
799
|
-
onClick?.(e);
|
|
800
|
-
if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) {
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
if (href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//")) {
|
|
804
|
-
return;
|
|
805
|
-
}
|
|
806
|
-
if (href.startsWith("#")) {
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
e.preventDefault();
|
|
810
|
-
if (replace) {
|
|
811
|
-
router.replace(href, { scroll });
|
|
812
|
-
} else {
|
|
813
|
-
router.navigate(href, { scroll });
|
|
814
|
-
}
|
|
815
|
-
},
|
|
816
|
-
[href, replace, scroll, router, onClick]
|
|
817
|
-
);
|
|
818
|
-
const handleMouseEnter = (0, import_react6.useCallback)(() => {
|
|
819
|
-
if (prefetch && !href.startsWith("http")) {
|
|
820
|
-
router.prefetch(href);
|
|
821
|
-
}
|
|
822
|
-
}, [href, prefetch, router]);
|
|
823
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
824
|
-
"a",
|
|
825
|
-
{
|
|
826
|
-
ref,
|
|
827
|
-
href,
|
|
828
|
-
onClick: handleClick,
|
|
829
|
-
onMouseEnter: handleMouseEnter,
|
|
830
|
-
...props,
|
|
831
|
-
children
|
|
832
|
-
}
|
|
833
|
-
);
|
|
834
|
-
}
|
|
835
|
-
);
|
|
836
|
-
Link.displayName = "Link";
|
|
837
|
-
var NavLink = (0, import_react6.forwardRef)(
|
|
838
|
-
({ href, activeClassName = "", inactiveClassName = "", exact = false, className = "", ...props }, ref) => {
|
|
839
|
-
const { pathname } = useOlovaRouter();
|
|
840
|
-
const isActive = exact ? pathname === href : pathname.startsWith(href) && (href === "/" ? pathname === "/" : true);
|
|
841
|
-
const combinedClassName = `${className} ${isActive ? activeClassName : inactiveClassName}`.trim();
|
|
842
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
843
|
-
Link,
|
|
844
|
-
{
|
|
845
|
-
ref,
|
|
846
|
-
href,
|
|
847
|
-
className: combinedClassName,
|
|
848
|
-
"aria-current": isActive ? "page" : void 0,
|
|
849
|
-
...props
|
|
850
|
-
}
|
|
851
|
-
);
|
|
852
|
-
}
|
|
853
|
-
);
|
|
854
|
-
NavLink.displayName = "NavLink";
|
|
855
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
856
|
-
0 && (module.exports = {
|
|
857
|
-
DefaultErrorComponent,
|
|
858
|
-
DefaultLoadingComponent,
|
|
859
|
-
DefaultNotFoundComponent,
|
|
860
|
-
Link,
|
|
861
|
-
MetadataHead,
|
|
862
|
-
MetadataProvider,
|
|
863
|
-
NavLink,
|
|
864
|
-
NotFoundBoundary,
|
|
865
|
-
NotFoundError,
|
|
866
|
-
OlovaRouter,
|
|
867
|
-
RouteErrorBoundary,
|
|
868
|
-
RouteLoadingBoundary,
|
|
869
|
-
Skeleton,
|
|
870
|
-
SkeletonCard,
|
|
871
|
-
SkeletonText,
|
|
872
|
-
generateMetadataHtml,
|
|
873
|
-
notFound,
|
|
874
|
-
setSSRContext,
|
|
875
|
-
useMetadata,
|
|
876
|
-
useOlovaRouter,
|
|
877
|
-
usePageMetadata,
|
|
878
|
-
useParams,
|
|
879
|
-
usePathname,
|
|
880
|
-
useRouter,
|
|
881
|
-
useSearchParams
|
|
882
|
-
});
|
|
883
|
-
//# sourceMappingURL=index.cjs.map
|