olova 2.0.61 → 2.0.63

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +42 -61
  3. package/dist/compiler.d.ts +44 -0
  4. package/dist/compiler.js +2139 -0
  5. package/dist/compiler.js.map +1 -0
  6. package/dist/core.d.ts +4 -0
  7. package/dist/core.js +859 -0
  8. package/dist/core.js.map +1 -0
  9. package/dist/global.d.ts +15 -0
  10. package/dist/global.js +226 -0
  11. package/dist/global.js.map +1 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +2302 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/runtime.d.ts +89 -0
  16. package/dist/runtime.js +633 -0
  17. package/dist/runtime.js.map +1 -0
  18. package/dist/signals-core-BdfWh1Yt.d.ts +43 -0
  19. package/dist/vite.d.ts +5 -0
  20. package/dist/vite.js +2302 -0
  21. package/dist/vite.js.map +1 -0
  22. package/package.json +83 -65
  23. package/dist/chunk-D7SIC5TC.js +0 -367
  24. package/dist/chunk-D7SIC5TC.js.map +0 -1
  25. package/dist/entry-server.cjs +0 -120
  26. package/dist/entry-server.cjs.map +0 -1
  27. package/dist/entry-server.js +0 -115
  28. package/dist/entry-server.js.map +0 -1
  29. package/dist/entry-worker.cjs +0 -133
  30. package/dist/entry-worker.cjs.map +0 -1
  31. package/dist/entry-worker.js +0 -127
  32. package/dist/entry-worker.js.map +0 -1
  33. package/dist/main.cjs +0 -18
  34. package/dist/main.cjs.map +0 -1
  35. package/dist/main.js +0 -16
  36. package/dist/main.js.map +0 -1
  37. package/dist/olova.cjs +0 -1680
  38. package/dist/olova.cjs.map +0 -1
  39. package/dist/olova.d.cts +0 -72
  40. package/dist/olova.d.ts +0 -72
  41. package/dist/olova.js +0 -1321
  42. package/dist/olova.js.map +0 -1
  43. package/dist/performance.cjs +0 -386
  44. package/dist/performance.cjs.map +0 -1
  45. package/dist/performance.js +0 -3
  46. package/dist/performance.js.map +0 -1
  47. package/dist/router.cjs +0 -646
  48. package/dist/router.cjs.map +0 -1
  49. package/dist/router.d.cts +0 -113
  50. package/dist/router.d.ts +0 -113
  51. package/dist/router.js +0 -632
  52. package/dist/router.js.map +0 -1
  53. package/main.tsx +0 -76
  54. package/olova.ts +0 -619
  55. package/src/entry-server.tsx +0 -165
  56. package/src/entry-worker.tsx +0 -201
  57. package/src/generator/index.ts +0 -409
  58. package/src/hydration/flight.ts +0 -320
  59. package/src/hydration/index.ts +0 -12
  60. package/src/hydration/types.ts +0 -225
  61. package/src/logger.ts +0 -182
  62. package/src/main.tsx +0 -24
  63. package/src/performance.ts +0 -488
  64. package/src/plugin/index.ts +0 -204
  65. package/src/router/ErrorBoundary.tsx +0 -145
  66. package/src/router/Link.tsx +0 -117
  67. package/src/router/OlovaRouter.tsx +0 -354
  68. package/src/router/Outlet.tsx +0 -8
  69. package/src/router/context.ts +0 -117
  70. package/src/router/index.ts +0 -29
  71. package/src/router/matching.ts +0 -63
  72. package/src/router/router.tsx +0 -23
  73. package/src/router/search-params.ts +0 -29
  74. package/src/scanner/index.ts +0 -114
  75. package/src/types/index.ts +0 -190
  76. package/src/utils/export.ts +0 -85
  77. package/src/utils/index.ts +0 -4
  78. package/src/utils/naming.ts +0 -54
  79. package/src/utils/path.ts +0 -45
  80. package/tsup.config.ts +0 -35
package/dist/router.cjs DELETED
@@ -1,646 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
- var jsxRuntime = require('react/jsx-runtime');
5
-
6
- // src/router/context.ts
7
- var RouterContext = react.createContext(null);
8
- var OutletContext = react.createContext(null);
9
- var ssrRouter = {
10
- currentPath: "/",
11
- params: {},
12
- searchParams: {},
13
- navigate: () => {
14
- },
15
- push: () => {
16
- },
17
- replace: () => {
18
- },
19
- back: () => {
20
- },
21
- forward: () => {
22
- },
23
- refresh: () => {
24
- },
25
- setSearchParams: () => {
26
- },
27
- isNavigating: false,
28
- prefetch: () => {
29
- }
30
- };
31
- function useRouter() {
32
- const context = react.useContext(RouterContext);
33
- if (!context) {
34
- if (typeof window === "undefined") return ssrRouter;
35
- throw new Error("useRouter must be used within OlovaRouter");
36
- }
37
- return context;
38
- }
39
- function useParams() {
40
- const context = react.useContext(RouterContext);
41
- return context?.params || {};
42
- }
43
- function useSearchParams() {
44
- const context = react.useContext(RouterContext);
45
- const searchParams = context?.searchParams || {};
46
- return react.useMemo(() => {
47
- const params = new URLSearchParams();
48
- Object.entries(searchParams).forEach(([key, value]) => {
49
- if (Array.isArray(value)) {
50
- value.forEach((v) => params.append(key, v));
51
- } else {
52
- params.set(key, value);
53
- }
54
- });
55
- return params;
56
- }, [searchParams]);
57
- }
58
- function usePathname() {
59
- const context = react.useContext(RouterContext);
60
- if (!context) {
61
- if (typeof window === "undefined") return "/";
62
- throw new Error("usePathname must be used within OlovaRouter");
63
- }
64
- return context.currentPath;
65
- }
66
- function useSelectedLayoutSegment() {
67
- const context = react.useContext(RouterContext);
68
- if (!context) return null;
69
- const segments = context.currentPath.split("/").filter(Boolean);
70
- return segments[0] || null;
71
- }
72
- function useSelectedLayoutSegments() {
73
- const context = react.useContext(RouterContext);
74
- if (!context) return [];
75
- return context.currentPath.split("/").filter(Boolean);
76
- }
77
- function useIsNavigating() {
78
- const context = react.useContext(RouterContext);
79
- return context?.isNavigating ?? false;
80
- }
81
- function useNavigationEvent(callback) {
82
- const context = react.useContext(RouterContext);
83
- const currentPath = context?.currentPath;
84
- const prevPath = react.useRef(currentPath || "/");
85
- react.useEffect(() => {
86
- if (!currentPath) return;
87
- if (prevPath.current !== currentPath) {
88
- callback(prevPath.current, currentPath);
89
- prevPath.current = currentPath;
90
- }
91
- }, [currentPath, callback]);
92
- }
93
- function redirect(path, options) {
94
- if (typeof window !== "undefined") {
95
- if (options?.replace) {
96
- window.history.replaceState({}, "", path);
97
- } else {
98
- window.history.pushState({}, "", path);
99
- }
100
- window.dispatchEvent(new PopStateEvent("popstate"));
101
- }
102
- throw new Error(`REDIRECT:${path}`);
103
- }
104
- function useRedirect() {
105
- const { navigate, replace } = useRouter();
106
- return react.useCallback((path, options) => {
107
- if (options?.replace) {
108
- replace(path, options);
109
- } else {
110
- navigate(path, options);
111
- }
112
- }, [navigate, replace]);
113
- }
114
- var ErrorBoundary = class extends react.Component {
115
- constructor(props) {
116
- super(props);
117
- this.state = { hasError: false, error: null };
118
- }
119
- static getDerivedStateFromError(error) {
120
- return { hasError: true, error };
121
- }
122
- componentDidCatch(error, errorInfo) {
123
- console.error("[olova] Uncaught error:", error, errorInfo);
124
- }
125
- handleReset = () => {
126
- this.setState({ hasError: false, error: null });
127
- };
128
- render() {
129
- if (this.state.hasError) {
130
- if (this.props.fallback) {
131
- return this.props.fallback;
132
- }
133
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
134
- padding: "2rem",
135
- maxWidth: "600px",
136
- margin: "4rem auto",
137
- fontFamily: "system-ui, -apple-system, sans-serif",
138
- textAlign: "center"
139
- }, children: [
140
- /* @__PURE__ */ jsxRuntime.jsx("h1", { style: { fontSize: "2rem", marginBottom: "1rem", color: "#e11d48" }, children: "Something went wrong" }),
141
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "#6b7280", marginBottom: "1.5rem" }, children: "An unexpected error occurred while rendering this page." }),
142
- this.state.error && /* @__PURE__ */ jsxRuntime.jsx("pre", { style: {
143
- padding: "1rem",
144
- backgroundColor: "#f3f4f6",
145
- borderRadius: "0.5rem",
146
- fontSize: "0.875rem",
147
- textAlign: "left",
148
- overflow: "auto",
149
- marginBottom: "1.5rem",
150
- color: "#374151"
151
- }, children: this.state.error.message }),
152
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "0.75rem", justifyContent: "center" }, children: [
153
- /* @__PURE__ */ jsxRuntime.jsx(
154
- "button",
155
- {
156
- onClick: this.handleReset,
157
- style: {
158
- padding: "0.5rem 1.5rem",
159
- backgroundColor: "#3b82f6",
160
- color: "white",
161
- border: "none",
162
- borderRadius: "0.375rem",
163
- cursor: "pointer",
164
- fontSize: "0.875rem"
165
- },
166
- children: "Try Again"
167
- }
168
- ),
169
- /* @__PURE__ */ jsxRuntime.jsx(
170
- "button",
171
- {
172
- onClick: () => window.location.reload(),
173
- style: {
174
- padding: "0.5rem 1.5rem",
175
- backgroundColor: "transparent",
176
- color: "#3b82f6",
177
- border: "1px solid #3b82f6",
178
- borderRadius: "0.375rem",
179
- cursor: "pointer",
180
- fontSize: "0.875rem"
181
- },
182
- children: "Reload Page"
183
- }
184
- )
185
- ] })
186
- ] });
187
- }
188
- return this.props.children;
189
- }
190
- };
191
- var RouteErrorBoundary = class extends react.Component {
192
- constructor(props) {
193
- super(props);
194
- this.state = { hasError: false, error: null };
195
- }
196
- static getDerivedStateFromError(error) {
197
- return { hasError: true, error };
198
- }
199
- componentDidUpdate(prevProps) {
200
- if (prevProps.routePath !== this.props.routePath && this.state.hasError) {
201
- this.setState({ hasError: false, error: null });
202
- }
203
- }
204
- componentDidCatch(error, errorInfo) {
205
- console.error("[olova] Route error:", error, errorInfo);
206
- }
207
- handleReset = () => {
208
- this.setState({ hasError: false, error: null });
209
- };
210
- render() {
211
- if (this.state.hasError && this.state.error) {
212
- const FallbackComponent = this.props.fallbackComponent;
213
- return /* @__PURE__ */ jsxRuntime.jsx(FallbackComponent, { error: this.state.error, reset: this.handleReset });
214
- }
215
- return this.props.children;
216
- }
217
- };
218
- function isActive(currentPath, href, exact) {
219
- const normalizedCurrent = currentPath.replace(/\/$/, "") || "/";
220
- const normalizedHref = href.split("?")[0].replace(/\/$/, "") || "/";
221
- if (exact) return normalizedCurrent === normalizedHref;
222
- if (normalizedHref === "/") return normalizedCurrent === "/";
223
- return normalizedCurrent === normalizedHref || normalizedCurrent.startsWith(normalizedHref + "/");
224
- }
225
- function createLink() {
226
- const Link = ({
227
- href,
228
- children,
229
- className,
230
- activeClassName,
231
- exactActiveClassName,
232
- prefetch = "hover",
233
- replace: shouldReplace = false,
234
- scroll = true,
235
- target,
236
- ...rest
237
- }) => {
238
- const { push, replace, currentPath, prefetch: prefetchRoute } = useRouter();
239
- const isSSR = typeof window === "undefined";
240
- const linkRef = react.useRef(null);
241
- const prefetched = react.useRef(false);
242
- const isExactActive = isActive(currentPath, href, true);
243
- const isPartialActive = isActive(currentPath, href, false);
244
- const computedClassName = [
245
- className,
246
- isPartialActive && activeClassName,
247
- isExactActive && exactActiveClassName
248
- ].filter(Boolean).join(" ") || void 0;
249
- const handlePrefetch = react.useCallback(() => {
250
- if (!prefetched.current && prefetch !== false) {
251
- prefetched.current = true;
252
- prefetchRoute(href);
253
- }
254
- }, [href, prefetch, prefetchRoute]);
255
- react.useEffect(() => {
256
- if (isSSR || prefetch !== "viewport" || !linkRef.current) return;
257
- const observer = new IntersectionObserver(
258
- (entries) => {
259
- if (entries[0]?.isIntersecting) {
260
- handlePrefetch();
261
- observer.disconnect();
262
- }
263
- },
264
- { rootMargin: "200px" }
265
- );
266
- observer.observe(linkRef.current);
267
- return () => observer.disconnect();
268
- }, [isSSR, prefetch, handlePrefetch]);
269
- const handleClick = (e) => {
270
- if (rest.onClick) rest.onClick(e);
271
- if (e.defaultPrevented) return;
272
- if (target === "_blank" || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
273
- e.preventDefault();
274
- const navFn = shouldReplace ? replace : push;
275
- navFn(href, { scroll });
276
- };
277
- return /* @__PURE__ */ jsxRuntime.jsx(
278
- "a",
279
- {
280
- ref: linkRef,
281
- href,
282
- className: computedClassName,
283
- "data-active": isPartialActive || void 0,
284
- "data-exact-active": isExactActive || void 0,
285
- onClick: isSSR ? void 0 : handleClick,
286
- onMouseEnter: isSSR || prefetch !== "hover" ? void 0 : handlePrefetch,
287
- onFocus: isSSR || prefetch !== "hover" ? void 0 : handlePrefetch,
288
- target,
289
- ...rest,
290
- children
291
- }
292
- );
293
- };
294
- return Link;
295
- }
296
-
297
- // src/router/matching.ts
298
- function matchRoute(patternParts, pathParts) {
299
- const params = {};
300
- const filteredPathParts = pathParts.filter(Boolean);
301
- const filteredPatternParts = patternParts.filter(Boolean);
302
- for (let i = 0; i < filteredPatternParts.length; i++) {
303
- const patternPart = filteredPatternParts[i];
304
- const pathPart = filteredPathParts[i];
305
- if (patternPart === "*") {
306
- params["*"] = filteredPathParts.slice(i).join("/");
307
- return { match: true, params };
308
- }
309
- if (pathPart === void 0) {
310
- return { match: false, params: {} };
311
- }
312
- if (patternPart.startsWith(":")) {
313
- params[patternPart.slice(1)] = decodeURIComponent(pathPart);
314
- } else if (patternPart !== pathPart) {
315
- return { match: false, params: {} };
316
- }
317
- }
318
- if (filteredPathParts.length > filteredPatternParts.length) {
319
- return { match: false, params: {} };
320
- }
321
- return { match: true, params };
322
- }
323
- function matchLayoutScope(layoutPath, pathname) {
324
- if (layoutPath === "/") return true;
325
- const normalizedPathname = pathname.replace(/\/+$/, "") || "/";
326
- const normalizedLayout = layoutPath.replace(/\/+$/, "") || "/";
327
- return normalizedPathname === normalizedLayout || normalizedPathname.startsWith(normalizedLayout + "/");
328
- }
329
- function findNotFoundPage(path, notFoundPages) {
330
- if (!notFoundPages || notFoundPages.length === 0) return null;
331
- const normalizedPath = path.replace(/\/+$/, "") || "/";
332
- const sorted = [...notFoundPages].sort(
333
- (a, b) => b.pathPrefix.length - a.pathPrefix.length
334
- );
335
- for (const nf of sorted) {
336
- if (nf.pathPrefix === "") {
337
- return nf.component;
338
- }
339
- if (normalizedPath === nf.pathPrefix || normalizedPath.startsWith(nf.pathPrefix + "/")) {
340
- return nf.component;
341
- }
342
- }
343
- return null;
344
- }
345
-
346
- // src/router/search-params.ts
347
- function parseSearchParams(search) {
348
- const params = {};
349
- const urlParams = new URLSearchParams(search);
350
- for (const key of urlParams.keys()) {
351
- const values = urlParams.getAll(key);
352
- params[key] = values.length === 1 ? values[0] : values;
353
- }
354
- return params;
355
- }
356
- function buildSearchString(params) {
357
- const urlParams = new URLSearchParams();
358
- for (const [key, value] of Object.entries(params)) {
359
- if (value === null || value === void 0) continue;
360
- if (Array.isArray(value)) {
361
- value.forEach((v) => urlParams.append(key, v));
362
- } else {
363
- urlParams.set(key, value);
364
- }
365
- }
366
- const str = urlParams.toString();
367
- return str ? `?${str}` : "";
368
- }
369
- function normalizePath(path) {
370
- if (path === "/") return path;
371
- return path.replace(/\/+$/, "") || "/";
372
- }
373
- function OlovaRouter({
374
- routes,
375
- layouts = [],
376
- notFoundPages = [],
377
- notFound = /* @__PURE__ */ jsxRuntime.jsx("div", { children: "404 - Not Found" }),
378
- loadingFallback = /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading..." }),
379
- initialPath,
380
- onNavigate,
381
- onBeforeNavigate
382
- }) {
383
- const isSSR = typeof window === "undefined";
384
- const [currentPath, setCurrentPath] = react.useState(() => normalizePath(initialPath || (isSSR ? "/" : window.location.pathname)));
385
- const [searchParams, setSearchParamsState] = react.useState(
386
- () => isSSR ? {} : parseSearchParams(window.location.search)
387
- );
388
- const [isPending, startTransition] = react.useTransition();
389
- const prevPathRef = react.useRef(currentPath);
390
- const [defaultTitle] = react.useState(() => isSSR ? "" : document.title);
391
- react.useEffect(() => {
392
- if (isSSR) return;
393
- const onPopState = () => {
394
- const newPath = normalizePath(window.location.pathname);
395
- startTransition(() => {
396
- setCurrentPath(newPath);
397
- setSearchParamsState(parseSearchParams(window.location.search));
398
- });
399
- };
400
- window.addEventListener("popstate", onPopState);
401
- return () => window.removeEventListener("popstate", onPopState);
402
- }, [isSSR]);
403
- const performNavigation = react.useCallback((path, options = {}, historyMethod = "push") => {
404
- if (isSSR) return;
405
- const { scroll = true } = options;
406
- const normalizedPath = normalizePath(path.split("?")[0].split("#")[0]);
407
- const hash = path.includes("#") ? "#" + path.split("#")[1] : "";
408
- const search = path.includes("?") ? "?" + path.split("?")[1].split("#")[0] : "";
409
- const fullUrl = normalizedPath + search + hash;
410
- if (onBeforeNavigate) {
411
- const result = onBeforeNavigate(currentPath, normalizedPath);
412
- if (result === false) return;
413
- }
414
- const prevPath = currentPath;
415
- if (historyMethod === "replace") {
416
- window.history.replaceState({}, "", fullUrl);
417
- } else {
418
- window.history.pushState({}, "", fullUrl);
419
- }
420
- startTransition(() => {
421
- setCurrentPath(normalizedPath);
422
- setSearchParamsState(parseSearchParams(search));
423
- });
424
- if (scroll) {
425
- if (hash) {
426
- const el = document.getElementById(hash.slice(1));
427
- if (el) {
428
- el.scrollIntoView({ behavior: "smooth" });
429
- } else {
430
- window.scrollTo(0, 0);
431
- }
432
- } else {
433
- window.scrollTo(0, 0);
434
- }
435
- }
436
- if (onNavigate) {
437
- onNavigate(prevPath, normalizedPath);
438
- }
439
- }, [isSSR, currentPath, onBeforeNavigate, onNavigate]);
440
- const navigate = react.useCallback((path, options) => {
441
- performNavigation(path, options, options?.replace ? "replace" : "push");
442
- }, [performNavigation]);
443
- const push = react.useCallback((path, options) => {
444
- performNavigation(path, options, "push");
445
- }, [performNavigation]);
446
- const replace = react.useCallback((path, options) => {
447
- performNavigation(path, options, "replace");
448
- }, [performNavigation]);
449
- const back = react.useCallback(() => {
450
- if (!isSSR) window.history.back();
451
- }, [isSSR]);
452
- const forward = react.useCallback(() => {
453
- if (!isSSR) window.history.forward();
454
- }, [isSSR]);
455
- const refresh = react.useCallback(() => {
456
- if (!isSSR) {
457
- startTransition(() => {
458
- setCurrentPath((prev) => prev);
459
- });
460
- }
461
- }, [isSSR]);
462
- const prefetch = react.useCallback((path) => {
463
- const normalizedPath = normalizePath(path.split("?")[0]);
464
- const pathParts = normalizedPath.split("/").filter(Boolean);
465
- for (const route of routes) {
466
- const segments = route.path.split("/").filter(Boolean);
467
- const result = matchRoute(segments, pathParts);
468
- if (result.match && route.component) {
469
- break;
470
- }
471
- }
472
- }, [routes]);
473
- const setSearchParams = react.useCallback((newParams, options = {}) => {
474
- if (isSSR) return;
475
- const { replace: shouldReplace = false, merge = false } = options;
476
- let finalParams;
477
- if (merge) {
478
- finalParams = { ...searchParams, ...newParams };
479
- for (const key of Object.keys(finalParams)) {
480
- if (finalParams[key] === null) {
481
- delete finalParams[key];
482
- }
483
- }
484
- } else {
485
- finalParams = newParams;
486
- }
487
- const searchString = buildSearchString(finalParams);
488
- const newUrl = currentPath + searchString;
489
- if (shouldReplace) {
490
- window.history.replaceState({}, "", newUrl);
491
- } else {
492
- window.history.pushState({}, "", newUrl);
493
- }
494
- setSearchParamsState(parseSearchParams(searchString));
495
- }, [isSSR, searchParams, currentPath]);
496
- const sortedRoutes = react.useMemo(() => {
497
- return [...routes].sort((a, b) => {
498
- const aHasCatchAll = a.path.includes("*");
499
- const bHasCatchAll = b.path.includes("*");
500
- const aHasDynamic = a.path.includes(":");
501
- const bHasDynamic = b.path.includes(":");
502
- if (aHasCatchAll && !bHasCatchAll) return 1;
503
- if (!aHasCatchAll && bHasCatchAll) return -1;
504
- if (aHasDynamic && !bHasDynamic) return 1;
505
- if (!aHasDynamic && bHasDynamic) return -1;
506
- return b.path.length - a.path.length;
507
- }).map((route) => ({
508
- ...route,
509
- segments: route.path.split("/").filter(Boolean)
510
- }));
511
- }, [routes]);
512
- const applyMetadata = react.useCallback((metadata) => {
513
- if (isSSR) return;
514
- if (metadata?.title) {
515
- document.title = metadata.title;
516
- } else {
517
- document.title = defaultTitle;
518
- }
519
- const setMetaTag = (name, content2, attr = "name") => {
520
- let meta = document.querySelector(`meta[${attr}="${name}"]`);
521
- if (content2) {
522
- if (!meta) {
523
- meta = document.createElement("meta");
524
- meta.setAttribute(attr, name);
525
- document.head.appendChild(meta);
526
- }
527
- meta.setAttribute("content", content2);
528
- } else if (meta) {
529
- document.head.removeChild(meta);
530
- }
531
- };
532
- setMetaTag("description", metadata?.description);
533
- setMetaTag(
534
- "keywords",
535
- metadata?.keywords ? Array.isArray(metadata.keywords) ? metadata.keywords.join(", ") : metadata.keywords : void 0
536
- );
537
- if (metadata?.openGraph) {
538
- setMetaTag("og:title", metadata.openGraph.title || metadata.title, "property");
539
- setMetaTag("og:description", metadata.openGraph.description || metadata.description, "property");
540
- setMetaTag("og:image", metadata.openGraph.image, "property");
541
- setMetaTag("og:url", metadata.openGraph.url, "property");
542
- setMetaTag("og:type", metadata.openGraph.type || "website", "property");
543
- }
544
- let canonical = document.querySelector('link[rel="canonical"]');
545
- if (metadata?.openGraph?.url) {
546
- if (!canonical) {
547
- canonical = document.createElement("link");
548
- canonical.setAttribute("rel", "canonical");
549
- document.head.appendChild(canonical);
550
- }
551
- canonical.setAttribute("href", metadata.openGraph.url);
552
- }
553
- }, [defaultTitle, isSSR]);
554
- const { currentRoute, MatchedComponent, params } = react.useMemo(() => {
555
- const pathParts = currentPath.split("/").filter(Boolean);
556
- for (const route of sortedRoutes) {
557
- if (route.path === "/" && currentPath === "/") {
558
- return {
559
- currentRoute: route,
560
- MatchedComponent: route.component || null,
561
- params: {}
562
- };
563
- }
564
- const result = matchRoute(route.segments, pathParts);
565
- if (result.match) {
566
- return {
567
- currentRoute: route,
568
- MatchedComponent: route.component || null,
569
- params: result.params
570
- };
571
- }
572
- }
573
- return {
574
- currentRoute: null,
575
- MatchedComponent: null,
576
- params: {}
577
- };
578
- }, [sortedRoutes, currentPath]);
579
- react.useEffect(() => {
580
- prevPathRef.current = currentPath;
581
- }, [currentPath]);
582
- react.useEffect(() => {
583
- if (isSSR) return;
584
- applyMetadata(currentRoute?.metadata);
585
- }, [currentRoute, applyMetadata, isSSR]);
586
- const matchingLayouts = react.useMemo(() => {
587
- return layouts.filter((layout) => matchLayoutScope(layout.path, currentPath)).sort((a, b) => a.path.length - b.path.length);
588
- }, [layouts, currentPath]);
589
- const FinalComponent = react.useMemo(() => {
590
- if (MatchedComponent) return MatchedComponent;
591
- return findNotFoundPage(currentPath, notFoundPages);
592
- }, [MatchedComponent, currentPath, notFoundPages]);
593
- const content = react.useMemo(() => {
594
- const LoadingComponent = currentRoute?.loading;
595
- const ErrorComponent = currentRoute?.error;
596
- let result = FinalComponent ? /* @__PURE__ */ jsxRuntime.jsx(FinalComponent, {}) : notFound;
597
- if (LoadingComponent) {
598
- result = /* @__PURE__ */ jsxRuntime.jsx(react.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingComponent, {}), children: result });
599
- }
600
- if (ErrorComponent) {
601
- result = /* @__PURE__ */ jsxRuntime.jsx(RouteErrorBoundary, { fallbackComponent: ErrorComponent, routePath: currentPath, children: result });
602
- }
603
- for (let i = matchingLayouts.length - 1; i >= 0; i--) {
604
- const Layout = matchingLayouts[i].layout;
605
- if (!Layout) continue;
606
- const wrapped = result;
607
- result = /* @__PURE__ */ jsxRuntime.jsx(OutletContext.Provider, { value: { content: wrapped }, children: /* @__PURE__ */ jsxRuntime.jsx(Layout, {}) });
608
- }
609
- return result;
610
- }, [FinalComponent, matchingLayouts, notFound, loadingFallback, currentRoute, currentPath]);
611
- return /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(RouterContext.Provider, { value: {
612
- currentPath,
613
- params,
614
- searchParams,
615
- navigate,
616
- push,
617
- replace,
618
- back,
619
- forward,
620
- refresh,
621
- setSearchParams,
622
- isNavigating: isPending,
623
- prefetch
624
- }, children: content }) });
625
- }
626
- function Outlet() {
627
- const context = react.useContext(OutletContext);
628
- if (!context) return null;
629
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: context.content });
630
- }
631
-
632
- exports.OlovaRouter = OlovaRouter;
633
- exports.Outlet = Outlet;
634
- exports.createLink = createLink;
635
- exports.redirect = redirect;
636
- exports.useIsNavigating = useIsNavigating;
637
- exports.useNavigationEvent = useNavigationEvent;
638
- exports.useParams = useParams;
639
- exports.usePathname = usePathname;
640
- exports.useRedirect = useRedirect;
641
- exports.useRouter = useRouter;
642
- exports.useSearchParams = useSearchParams;
643
- exports.useSelectedLayoutSegment = useSelectedLayoutSegment;
644
- exports.useSelectedLayoutSegments = useSelectedLayoutSegments;
645
- //# sourceMappingURL=router.cjs.map
646
- //# sourceMappingURL=router.cjs.map