olova 2.0.17 → 2.0.18

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/dist/Link.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import React__default, { ReactNode } from 'react';
2
+
3
+ declare function Link({ href, children, ...props }: {
4
+ href: string;
5
+ children: ReactNode;
6
+ } & React__default.AnchorHTMLAttributes<HTMLAnchorElement>): React__default.ReactElement;
7
+
8
+ export { Link, Link as default };
package/dist/Link.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ Link,
3
+ Link_default
4
+ } from "./chunk-WNRULQF5.js";
5
+ import "./chunk-TFRUFD5A.js";
6
+ export {
7
+ Link,
8
+ Link_default as default
9
+ };
@@ -0,0 +1,53 @@
1
+ import React__default from 'react';
2
+
3
+ interface Metadata {
4
+ title?: string;
5
+ description?: string;
6
+ keywords?: string | string[];
7
+ openGraph?: {
8
+ title?: string;
9
+ description?: string;
10
+ url?: string;
11
+ siteName?: string;
12
+ images?: {
13
+ url: string;
14
+ width?: number;
15
+ height?: number;
16
+ alt?: string;
17
+ }[];
18
+ type?: string;
19
+ };
20
+ twitter?: {
21
+ card?: 'summary' | 'summary_large_image' | 'app' | 'player';
22
+ site?: string;
23
+ creator?: string;
24
+ title?: string;
25
+ description?: string;
26
+ images?: string[];
27
+ };
28
+ robots?: string;
29
+ canonical?: string;
30
+ jsonLd?: object | object[];
31
+ }
32
+ declare function matchRoute(path: string): {
33
+ loader: any;
34
+ params: Record<string, string>;
35
+ pattern: string;
36
+ } | null;
37
+ declare function loadRoute(path: string): Promise<{
38
+ module: any;
39
+ params: Record<string, string>;
40
+ metadata: Metadata | undefined;
41
+ } | null>;
42
+ interface RouterProps {
43
+ url?: string;
44
+ initialComponent?: React__default.ComponentType;
45
+ initialParams?: Record<string, string>;
46
+ onRouteChange?: (metadata: Metadata | undefined) => void;
47
+ }
48
+ declare function Router({ url, initialComponent, initialParams, onRouteChange }: RouterProps): React__default.DetailedReactHTMLElement<React__default.HTMLAttributes<HTMLElement>, HTMLElement> | React__default.FunctionComponentElement<React__default.ProviderProps<{
49
+ params: Record<string, string>;
50
+ path: string;
51
+ }>>;
52
+
53
+ export { type Metadata, Router, loadRoute, matchRoute };
package/dist/Router.js ADDED
@@ -0,0 +1,12 @@
1
+ import {
2
+ Router,
3
+ loadRoute,
4
+ matchRoute
5
+ } from "./chunk-4CH3KNWP.js";
6
+ import "./chunk-7BXNTMPM.js";
7
+ import "./chunk-TFRUFD5A.js";
8
+ export {
9
+ Router,
10
+ loadRoute,
11
+ matchRoute
12
+ };
@@ -0,0 +1,157 @@
1
+ import {
2
+ RouterContext
3
+ } from "./chunk-7BXNTMPM.js";
4
+ import {
5
+ __toESM,
6
+ require_react
7
+ } from "./chunk-TFRUFD5A.js";
8
+
9
+ // Router.tsx
10
+ var import_react = __toESM(require_react(), 1);
11
+ import { routes } from "olova/routes";
12
+ function parseMarkdown(md) {
13
+ return md.replace(/^### (.*$)/gim, "<h3>$1</h3>").replace(/^## (.*$)/gim, "<h2>$1</h2>").replace(/^# (.*$)/gim, "<h1>$1</h1>").replace(/\*\*\*(.*?)\*\*\*/g, "<strong><em>$1</em></strong>").replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>").replace(/\*(.*?)\*/g, "<em>$1</em>").replace(/```([\s\S]*?)```/g, "<pre><code>$1</code></pre>").replace(/`(.*?)`/g, "<code>$1</code>").replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>').replace(/\n\n/g, "</p><p>").replace(/\n/g, "<br>").replace(/^(.*)$/, "<p>$1</p>");
14
+ }
15
+ function HtmlContent({ html }) {
16
+ return import_react.default.createElement("div", {
17
+ dangerouslySetInnerHTML: { __html: html },
18
+ className: "olova-html-content"
19
+ });
20
+ }
21
+ function MarkdownContent({ markdown }) {
22
+ const html = parseMarkdown(markdown);
23
+ return import_react.default.createElement("article", {
24
+ dangerouslySetInnerHTML: { __html: html },
25
+ className: "olova-markdown-content"
26
+ });
27
+ }
28
+ var normalizePath = (path) => {
29
+ let p = path.split("?")[0].split("#")[0];
30
+ if (p.length > 1 && p.endsWith("/")) p = p.slice(0, -1);
31
+ return p || "/";
32
+ };
33
+ function matchRoute(path) {
34
+ const normalizedPath = normalizePath(path);
35
+ const routeKeys = Object.keys(routes);
36
+ for (const route of routeKeys) {
37
+ if (route === normalizedPath) {
38
+ return { loader: routes[route], params: {}, pattern: route };
39
+ }
40
+ const regexPath = route.replace(/:[^\/]+/g, "([^/]+)").replace(/\$[^\/]+/g, "([^/]+)");
41
+ const regex = new RegExp(`^${regexPath}$`);
42
+ const match = normalizedPath.match(regex);
43
+ if (match) {
44
+ const params = {};
45
+ const paramNames = (route.match(/[:$][^\/]+/g) || []).map((s) => s.slice(1));
46
+ paramNames.forEach((name, i) => {
47
+ params[name] = match[i + 1];
48
+ });
49
+ return { loader: routes[route], params, pattern: route };
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+ async function loadRoute(path) {
55
+ const match = matchRoute(path);
56
+ if (match) {
57
+ console.log(`[Router] Loading route: ${path} (pattern: ${match.pattern})`);
58
+ const module = await match.loader();
59
+ if (module.__isHtml) {
60
+ return {
61
+ module: {
62
+ default: () => HtmlContent({ html: module.__rawHtml })
63
+ },
64
+ params: match.params,
65
+ metadata: void 0
66
+ };
67
+ }
68
+ if (module.__isMd) {
69
+ return {
70
+ module: {
71
+ default: () => MarkdownContent({ markdown: module.default })
72
+ },
73
+ params: match.params,
74
+ metadata: void 0
75
+ };
76
+ }
77
+ return {
78
+ module,
79
+ params: match.params,
80
+ metadata: module.metadata
81
+ };
82
+ }
83
+ console.warn(`[Router] No match for: ${path}`);
84
+ return null;
85
+ }
86
+ function Router({ url, initialComponent, initialParams, onRouteChange }) {
87
+ const [path, setPath] = (0, import_react.useState)(() => normalizePath(url || (typeof window !== "undefined" ? window.location.pathname : "/")));
88
+ const [Component, setComponent] = (0, import_react.useState)(() => initialComponent || null);
89
+ const [params, setParams] = (0, import_react.useState)(() => initialParams || {});
90
+ const hasHydrated = import_react.default.useRef(false);
91
+ (0, import_react.useEffect)(() => {
92
+ if (typeof window === "undefined") return;
93
+ const handleNavigation = () => {
94
+ const newPath = normalizePath(window.location.pathname);
95
+ console.log(`[Router] Navigation event: ${newPath}`);
96
+ setPath(newPath);
97
+ };
98
+ window.addEventListener("popstate", handleNavigation);
99
+ window.addEventListener("pushstate", handleNavigation);
100
+ return () => {
101
+ window.removeEventListener("popstate", handleNavigation);
102
+ window.removeEventListener("pushstate", handleNavigation);
103
+ };
104
+ }, []);
105
+ (0, import_react.useEffect)(() => {
106
+ if (!hasHydrated.current && initialComponent && path === normalizePath(url || "")) {
107
+ console.log(`[Router] Hydration skipped for: ${path}`);
108
+ hasHydrated.current = true;
109
+ return;
110
+ }
111
+ let isCancelled = false;
112
+ const load = async () => {
113
+ const result = await loadRoute(path);
114
+ if (!isCancelled) {
115
+ if (result) {
116
+ setComponent(() => result.module.default);
117
+ setParams(result.params);
118
+ if (onRouteChange) {
119
+ onRouteChange(result.metadata);
120
+ }
121
+ } else {
122
+ const fallbackResult = await loadRoute("/404");
123
+ if (fallbackResult) {
124
+ console.log("[Router] Serving custom 404 page");
125
+ setComponent(() => fallbackResult.module.default);
126
+ setParams(fallbackResult.params);
127
+ if (onRouteChange) {
128
+ onRouteChange(fallbackResult.metadata);
129
+ }
130
+ } else {
131
+ setComponent(() => () => import_react.default.createElement("div", null, "404 Not Found"));
132
+ setParams({});
133
+ if (onRouteChange) {
134
+ onRouteChange(void 0);
135
+ }
136
+ }
137
+ }
138
+ }
139
+ };
140
+ load();
141
+ return () => {
142
+ isCancelled = true;
143
+ };
144
+ }, [path, onRouteChange]);
145
+ if (!Component) return import_react.default.createElement("div", null, "Loading...");
146
+ return import_react.default.createElement(
147
+ RouterContext.Provider,
148
+ { value: { params, path } },
149
+ import_react.default.createElement(Component, params)
150
+ );
151
+ }
152
+
153
+ export {
154
+ matchRoute,
155
+ loadRoute,
156
+ Router
157
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ __toESM,
3
+ require_react
4
+ } from "./chunk-TFRUFD5A.js";
5
+
6
+ // context.ts
7
+ var import_react = __toESM(require_react(), 1);
8
+ var RouterContext = (0, import_react.createContext)({ params: {}, path: "/" });
9
+
10
+ export {
11
+ RouterContext
12
+ };
@@ -0,0 +1,44 @@
1
+ import {
2
+ __toESM,
3
+ require_react
4
+ } from "./chunk-TFRUFD5A.js";
5
+
6
+ // useSearchParams.ts
7
+ var import_react = __toESM(require_react(), 1);
8
+ function useSearchParams() {
9
+ const [searchParams, setSearchParams] = (0, import_react.useState)(() => {
10
+ if (typeof window === "undefined") return new URLSearchParams();
11
+ return new URLSearchParams(window.location.search);
12
+ });
13
+ (0, import_react.useEffect)(() => {
14
+ if (typeof window === "undefined") return;
15
+ const handleNavigation = () => {
16
+ setSearchParams(new URLSearchParams(window.location.search));
17
+ };
18
+ window.addEventListener("popstate", handleNavigation);
19
+ window.addEventListener("pushstate", handleNavigation);
20
+ return () => {
21
+ window.removeEventListener("popstate", handleNavigation);
22
+ window.removeEventListener("pushstate", handleNavigation);
23
+ };
24
+ }, []);
25
+ return {
26
+ get: (name) => searchParams.get(name),
27
+ getAll: (name) => searchParams.getAll(name),
28
+ has: (name) => searchParams.has(name),
29
+ keys: () => searchParams.keys(),
30
+ values: () => searchParams.values(),
31
+ entries: () => searchParams.entries(),
32
+ forEach: (callback) => searchParams.forEach(callback),
33
+ toString: () => searchParams.toString(),
34
+ get size() {
35
+ return Array.from(searchParams.keys()).length;
36
+ }
37
+ };
38
+ }
39
+ var useSearchParams_default = useSearchParams;
40
+
41
+ export {
42
+ useSearchParams,
43
+ useSearchParams_default
44
+ };
@@ -0,0 +1,32 @@
1
+ import {
2
+ __toESM,
3
+ require_react
4
+ } from "./chunk-TFRUFD5A.js";
5
+
6
+ // usePathname.ts
7
+ var import_react = __toESM(require_react(), 1);
8
+ function usePathname() {
9
+ const [pathname, setPathname] = (0, import_react.useState)(() => {
10
+ if (typeof window === "undefined") return "/";
11
+ return window.location.pathname;
12
+ });
13
+ (0, import_react.useEffect)(() => {
14
+ if (typeof window === "undefined") return;
15
+ const handleNavigation = () => {
16
+ setPathname(window.location.pathname);
17
+ };
18
+ window.addEventListener("popstate", handleNavigation);
19
+ window.addEventListener("pushstate", handleNavigation);
20
+ return () => {
21
+ window.removeEventListener("popstate", handleNavigation);
22
+ window.removeEventListener("pushstate", handleNavigation);
23
+ };
24
+ }, []);
25
+ return pathname;
26
+ }
27
+ var usePathname_default = usePathname;
28
+
29
+ export {
30
+ usePathname,
31
+ usePathname_default
32
+ };