reroute-js 0.0.1
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 +144 -0
- package/cli/bin.d.ts +3 -0
- package/cli/bin.d.ts.map +1 -0
- package/cli/bin.js +812 -0
- package/cli/bin.js.map +15 -0
- package/cli/src/commands/build.d.ts +8 -0
- package/cli/src/commands/build.d.ts.map +1 -0
- package/cli/src/commands/dev.d.ts +8 -0
- package/cli/src/commands/dev.d.ts.map +1 -0
- package/cli/src/commands/gen.d.ts +3 -0
- package/cli/src/commands/gen.d.ts.map +1 -0
- package/cli/src/commands/init.d.ts +8 -0
- package/cli/src/commands/init.d.ts.map +1 -0
- package/cli/src/index.d.ts +8 -0
- package/cli/src/index.d.ts.map +1 -0
- package/cli/src/libs/tailwind.d.ts +18 -0
- package/cli/src/libs/tailwind.d.ts.map +1 -0
- package/core/index.d.ts +2 -0
- package/core/index.d.ts.map +1 -0
- package/core/index.js +1174 -0
- package/core/index.js.map +25 -0
- package/core/src/bundler/hash.d.ts +2 -0
- package/core/src/bundler/hash.d.ts.map +1 -0
- package/core/src/bundler/index.d.ts +3 -0
- package/core/src/bundler/index.d.ts.map +1 -0
- package/core/src/bundler/transpile.d.ts +4 -0
- package/core/src/bundler/transpile.d.ts.map +1 -0
- package/core/src/content/builder.d.ts +2 -0
- package/core/src/content/builder.d.ts.map +1 -0
- package/core/src/content/discovery.d.ts +5 -0
- package/core/src/content/discovery.d.ts.map +1 -0
- package/core/src/content/index.d.ts +5 -0
- package/core/src/content/index.d.ts.map +1 -0
- package/core/src/content/metadata.d.ts +9 -0
- package/core/src/content/metadata.d.ts.map +1 -0
- package/core/src/content/registry.d.ts +2 -0
- package/core/src/content/registry.d.ts.map +1 -0
- package/core/src/index.d.ts +7 -0
- package/core/src/index.d.ts.map +1 -0
- package/core/src/ssr/data.d.ts +9 -0
- package/core/src/ssr/data.d.ts.map +1 -0
- package/core/src/ssr/index.d.ts +4 -0
- package/core/src/ssr/index.d.ts.map +1 -0
- package/core/src/ssr/modules.d.ts +8 -0
- package/core/src/ssr/modules.d.ts.map +1 -0
- package/core/src/ssr/render.d.ts +20 -0
- package/core/src/ssr/render.d.ts.map +1 -0
- package/core/src/ssr/seed.d.ts +2 -0
- package/core/src/ssr/seed.d.ts.map +1 -0
- package/core/src/template/html.d.ts +4 -0
- package/core/src/template/html.d.ts.map +1 -0
- package/core/src/template/index.d.ts +2 -0
- package/core/src/template/index.d.ts.map +1 -0
- package/core/src/types.d.ts +50 -0
- package/core/src/types.d.ts.map +1 -0
- package/core/src/utils/cache.d.ts +12 -0
- package/core/src/utils/cache.d.ts.map +1 -0
- package/core/src/utils/compression.d.ts +5 -0
- package/core/src/utils/compression.d.ts.map +1 -0
- package/core/src/utils/index.d.ts +5 -0
- package/core/src/utils/index.d.ts.map +1 -0
- package/core/src/utils/mime.d.ts +3 -0
- package/core/src/utils/mime.d.ts.map +1 -0
- package/core/src/utils/path.d.ts +6 -0
- package/core/src/utils/path.d.ts.map +1 -0
- package/elysia/index.d.ts +2 -0
- package/elysia/index.d.ts.map +1 -0
- package/elysia/index.js +1829 -0
- package/elysia/index.js.map +32 -0
- package/elysia/src/index.d.ts +3 -0
- package/elysia/src/index.d.ts.map +1 -0
- package/elysia/src/plugin.d.ts +32 -0
- package/elysia/src/plugin.d.ts.map +1 -0
- package/elysia/src/routes/artifacts.d.ts +3 -0
- package/elysia/src/routes/artifacts.d.ts.map +1 -0
- package/elysia/src/routes/content.d.ts +3 -0
- package/elysia/src/routes/content.d.ts.map +1 -0
- package/elysia/src/routes/dev.d.ts +7 -0
- package/elysia/src/routes/dev.d.ts.map +1 -0
- package/elysia/src/routes/ssr.d.ts +18 -0
- package/elysia/src/routes/ssr.d.ts.map +1 -0
- package/elysia/src/routes/static.d.ts +19 -0
- package/elysia/src/routes/static.d.ts.map +1 -0
- package/elysia/src/types.d.ts +31 -0
- package/elysia/src/types.d.ts.map +1 -0
- package/elysia/src/utils/http.d.ts +5 -0
- package/elysia/src/utils/http.d.ts.map +1 -0
- package/package.json +74 -0
- package/react/index.d.ts +2 -0
- package/react/index.d.ts.map +1 -0
- package/react/index.js +1152 -0
- package/react/index.js.map +23 -0
- package/react/src/components/ContentRoute.d.ts +13 -0
- package/react/src/components/ContentRoute.d.ts.map +1 -0
- package/react/src/components/Link.d.ts +8 -0
- package/react/src/components/Link.d.ts.map +1 -0
- package/react/src/components/Outlet.d.ts +7 -0
- package/react/src/components/Outlet.d.ts.map +1 -0
- package/react/src/components/index.d.ts +4 -0
- package/react/src/components/index.d.ts.map +1 -0
- package/react/src/hooks/index.d.ts +7 -0
- package/react/src/hooks/index.d.ts.map +1 -0
- package/react/src/hooks/useContent.d.ts +26 -0
- package/react/src/hooks/useContent.d.ts.map +1 -0
- package/react/src/hooks/useData.d.ts +10 -0
- package/react/src/hooks/useData.d.ts.map +1 -0
- package/react/src/hooks/useNavigate.d.ts +6 -0
- package/react/src/hooks/useNavigate.d.ts.map +1 -0
- package/react/src/hooks/useParams.d.ts +6 -0
- package/react/src/hooks/useParams.d.ts.map +1 -0
- package/react/src/hooks/useRouter.d.ts +7 -0
- package/react/src/hooks/useRouter.d.ts.map +1 -0
- package/react/src/hooks/useSearchParams.d.ts +6 -0
- package/react/src/hooks/useSearchParams.d.ts.map +1 -0
- package/react/src/index.d.ts +6 -0
- package/react/src/index.d.ts.map +1 -0
- package/react/src/providers/ContentProvider.d.ts +35 -0
- package/react/src/providers/ContentProvider.d.ts.map +1 -0
- package/react/src/providers/RerouteProvider.d.ts +25 -0
- package/react/src/providers/RerouteProvider.d.ts.map +1 -0
- package/react/src/providers/RouterProvider.d.ts +23 -0
- package/react/src/providers/RouterProvider.d.ts.map +1 -0
- package/react/src/providers/index.d.ts +4 -0
- package/react/src/providers/index.d.ts.map +1 -0
- package/react/src/types/any.d.ts +3 -0
- package/react/src/types/any.d.ts.map +1 -0
- package/react/src/types/index.d.ts +3 -0
- package/react/src/types/index.d.ts.map +1 -0
- package/react/src/types/router.d.ts +32 -0
- package/react/src/types/router.d.ts.map +1 -0
- package/react/src/utils/content.d.ts +8 -0
- package/react/src/utils/content.d.ts.map +1 -0
- package/react/src/utils/head.d.ts +6 -0
- package/react/src/utils/head.d.ts.map +1 -0
- package/react/src/utils/index.d.ts +3 -0
- package/react/src/utils/index.d.ts.map +1 -0
package/react/index.js
ADDED
|
@@ -0,0 +1,1152 @@
|
|
|
1
|
+
// packages/react/src/components/ContentRoute.tsx
|
|
2
|
+
import {
|
|
3
|
+
isValidElement,
|
|
4
|
+
useEffect as useEffect4,
|
|
5
|
+
useMemo as useMemo5,
|
|
6
|
+
useState as useState4
|
|
7
|
+
} from "react";
|
|
8
|
+
|
|
9
|
+
// packages/react/src/hooks/useContent.ts
|
|
10
|
+
import { useCallback as useCallback2, useEffect, useMemo as useMemo2, useState as useState2 } from "react";
|
|
11
|
+
|
|
12
|
+
// packages/react/src/providers/ContentProvider.tsx
|
|
13
|
+
import {
|
|
14
|
+
createContext,
|
|
15
|
+
useCallback,
|
|
16
|
+
useContext,
|
|
17
|
+
useMemo,
|
|
18
|
+
useState
|
|
19
|
+
} from "react";
|
|
20
|
+
|
|
21
|
+
// packages/react/src/utils/content.ts
|
|
22
|
+
function parseContentHref(href) {
|
|
23
|
+
try {
|
|
24
|
+
const url = new URL(href, "http://local");
|
|
25
|
+
const [collection, name] = url.pathname.split("/").filter(Boolean);
|
|
26
|
+
if (!collection || !name)
|
|
27
|
+
return;
|
|
28
|
+
return { collection, name };
|
|
29
|
+
} catch {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function createResolverFromGetEntry(getEntry) {
|
|
34
|
+
return (href) => {
|
|
35
|
+
const parsed = parseContentHref(href);
|
|
36
|
+
if (!parsed)
|
|
37
|
+
return;
|
|
38
|
+
try {
|
|
39
|
+
const entry = getEntry(parsed.collection, parsed.name);
|
|
40
|
+
if (!entry)
|
|
41
|
+
return parsed;
|
|
42
|
+
const moduleUrl = entry?.module;
|
|
43
|
+
return moduleUrl ? { ...parsed, module: moduleUrl } : parsed;
|
|
44
|
+
} catch {
|
|
45
|
+
return parsed;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// packages/react/src/providers/ContentProvider.tsx
|
|
51
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
52
|
+
var ContentRegistryContext = createContext(null);
|
|
53
|
+
var ContentIndexContext = createContext(null);
|
|
54
|
+
var ContentGetEntryContext = createContext(null);
|
|
55
|
+
var ContentLoadCollectionContext = createContext(null);
|
|
56
|
+
function ContentProvider({
|
|
57
|
+
children,
|
|
58
|
+
resolveByHref,
|
|
59
|
+
getEntry,
|
|
60
|
+
byCollection,
|
|
61
|
+
loadCollection
|
|
62
|
+
}) {
|
|
63
|
+
const [idx, setIdx] = useState(() => {
|
|
64
|
+
const seededClient = (() => {
|
|
65
|
+
try {
|
|
66
|
+
if (typeof window !== "undefined") {
|
|
67
|
+
const w = window;
|
|
68
|
+
return w.__REROUTE_COLLECTIONS__ || {};
|
|
69
|
+
}
|
|
70
|
+
} catch {}
|
|
71
|
+
return {};
|
|
72
|
+
})();
|
|
73
|
+
const seededServer = (() => {
|
|
74
|
+
try {
|
|
75
|
+
if (typeof window === "undefined") {
|
|
76
|
+
const g = globalThis;
|
|
77
|
+
return g.__REROUTE_COLLECTIONS__ || {};
|
|
78
|
+
}
|
|
79
|
+
} catch {}
|
|
80
|
+
return {};
|
|
81
|
+
})();
|
|
82
|
+
return {
|
|
83
|
+
...byCollection || {},
|
|
84
|
+
...seededServer,
|
|
85
|
+
...seededClient
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
const entryFn = getEntry || null;
|
|
89
|
+
const resolver = useMemo(() => {
|
|
90
|
+
if (typeof resolveByHref === "function")
|
|
91
|
+
return resolveByHref;
|
|
92
|
+
if (typeof getEntry === "function")
|
|
93
|
+
return createResolverFromGetEntry(getEntry);
|
|
94
|
+
return (href) => {
|
|
95
|
+
const parsed = parseContentHref(href);
|
|
96
|
+
if (!parsed)
|
|
97
|
+
return;
|
|
98
|
+
try {
|
|
99
|
+
const list = idx?.[parsed.collection];
|
|
100
|
+
if (Array.isArray(list)) {
|
|
101
|
+
const found = list.find((e) => e?.name === parsed.name);
|
|
102
|
+
if (found && typeof found.module === "string") {
|
|
103
|
+
return { ...parsed, module: found.module };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} catch {}
|
|
107
|
+
return parsed;
|
|
108
|
+
};
|
|
109
|
+
}, [resolveByHref, getEntry, idx]);
|
|
110
|
+
const ensureCollection = useCallback(async (collection) => {
|
|
111
|
+
try {
|
|
112
|
+
const existing = idx[collection];
|
|
113
|
+
if (Array.isArray(existing) && existing.length)
|
|
114
|
+
return existing;
|
|
115
|
+
if (!loadCollection)
|
|
116
|
+
return existing;
|
|
117
|
+
const mod = await loadCollection(collection);
|
|
118
|
+
const items = mod.items || mod.list || [];
|
|
119
|
+
if (Array.isArray(items)) {
|
|
120
|
+
setIdx((prev) => ({ ...prev || {}, [collection]: items }));
|
|
121
|
+
return items;
|
|
122
|
+
}
|
|
123
|
+
return existing;
|
|
124
|
+
} catch {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
}, [idx, loadCollection]);
|
|
128
|
+
return /* @__PURE__ */ jsxDEV(ContentRegistryContext.Provider, {
|
|
129
|
+
value: resolver,
|
|
130
|
+
children: /* @__PURE__ */ jsxDEV(ContentIndexContext.Provider, {
|
|
131
|
+
value: idx,
|
|
132
|
+
children: /* @__PURE__ */ jsxDEV(ContentGetEntryContext.Provider, {
|
|
133
|
+
value: entryFn,
|
|
134
|
+
children: /* @__PURE__ */ jsxDEV(ContentLoadCollectionContext.Provider, {
|
|
135
|
+
value: ensureCollection,
|
|
136
|
+
children
|
|
137
|
+
}, undefined, false, undefined, this)
|
|
138
|
+
}, undefined, false, undefined, this)
|
|
139
|
+
}, undefined, false, undefined, this)
|
|
140
|
+
}, undefined, false, undefined, this);
|
|
141
|
+
}
|
|
142
|
+
function useContentResolver() {
|
|
143
|
+
return useContext(ContentRegistryContext);
|
|
144
|
+
}
|
|
145
|
+
function useContentIndex() {
|
|
146
|
+
return useContext(ContentIndexContext);
|
|
147
|
+
}
|
|
148
|
+
function useContentGetEntry() {
|
|
149
|
+
return useContext(ContentGetEntryContext);
|
|
150
|
+
}
|
|
151
|
+
function useContentLoadCollection() {
|
|
152
|
+
return useContext(ContentLoadCollectionContext);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// packages/react/src/hooks/useContent.ts
|
|
156
|
+
function sortByDate(order) {
|
|
157
|
+
return (a, b) => {
|
|
158
|
+
const da = a?.meta && a.meta?.date ? Date.parse(String(a.meta.date)) : 0;
|
|
159
|
+
const db = b?.meta && b.meta?.date ? Date.parse(String(b.meta.date)) : 0;
|
|
160
|
+
return order === "asc" ? da - db : db - da;
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function prefetchContent(entry) {
|
|
164
|
+
if (typeof window === "undefined")
|
|
165
|
+
return;
|
|
166
|
+
const modUrl = entry?.module;
|
|
167
|
+
if (!modUrl || typeof modUrl !== "string")
|
|
168
|
+
return;
|
|
169
|
+
try {
|
|
170
|
+
const key = `${entry.collection}:${entry.name}`;
|
|
171
|
+
const w = window;
|
|
172
|
+
if (!w.__REROUTE_MODULES__)
|
|
173
|
+
w.__REROUTE_MODULES__ = {};
|
|
174
|
+
const store = w.__REROUTE_MODULES__;
|
|
175
|
+
if (store[key])
|
|
176
|
+
return;
|
|
177
|
+
import(modUrl).then((m) => {
|
|
178
|
+
const C = m.default || m;
|
|
179
|
+
store[key] = C;
|
|
180
|
+
}).catch(() => {});
|
|
181
|
+
} catch {}
|
|
182
|
+
}
|
|
183
|
+
function useContent(params) {
|
|
184
|
+
const { collection, sort = { date: "desc" }, limit } = params;
|
|
185
|
+
try {
|
|
186
|
+
if (typeof window === "undefined") {
|
|
187
|
+
const g = globalThis;
|
|
188
|
+
if (!g.__REROUTE_SSR_ACCESSED__) {
|
|
189
|
+
g.__REROUTE_SSR_ACCESSED__ = {};
|
|
190
|
+
}
|
|
191
|
+
const rec = g.__REROUTE_SSR_ACCESSED__;
|
|
192
|
+
const existing = rec[collection] || {};
|
|
193
|
+
const isCustomSort = typeof sort === "function";
|
|
194
|
+
const sortKey = isCustomSort ? "custom" : sort === false ? "none" : typeof sort === "string" ? sort === "date-asc" ? "date-asc" : "date-desc" : typeof sort === "object" && sort && sort.date === "asc" ? "date-asc" : "date-desc";
|
|
195
|
+
existing.sort = existing.sort && existing.sort !== sortKey ? "custom" : existing.sort || sortKey;
|
|
196
|
+
const requested = typeof limit === "number" && limit > 0 ? limit : Infinity;
|
|
197
|
+
existing.limit = Math.max(existing.limit || 0, requested);
|
|
198
|
+
rec[collection] = existing;
|
|
199
|
+
}
|
|
200
|
+
} catch {}
|
|
201
|
+
const index = useContentIndex();
|
|
202
|
+
const loadCollection = useContentLoadCollection();
|
|
203
|
+
const [_ready, setReady] = useState2(false);
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
let cancelled = false;
|
|
206
|
+
async function ensure() {
|
|
207
|
+
try {
|
|
208
|
+
const have = index?.[collection];
|
|
209
|
+
const w = typeof window !== "undefined" ? window : undefined;
|
|
210
|
+
const partial = Boolean(w?.__REROUTE_COLLECTIONS_PARTIAL__?.[collection]);
|
|
211
|
+
if (!have || partial && (!limit || typeof limit === "number" && have.length < limit)) {
|
|
212
|
+
if (loadCollection)
|
|
213
|
+
await loadCollection(collection);
|
|
214
|
+
}
|
|
215
|
+
} finally {
|
|
216
|
+
if (!cancelled)
|
|
217
|
+
setReady(true);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
ensure();
|
|
221
|
+
return () => {
|
|
222
|
+
cancelled = true;
|
|
223
|
+
};
|
|
224
|
+
}, [collection, index, loadCollection, limit]);
|
|
225
|
+
const items = useMemo2(() => {
|
|
226
|
+
const source = index || {};
|
|
227
|
+
const list = source?.[collection];
|
|
228
|
+
if (!Array.isArray(list) || list.length === 0)
|
|
229
|
+
return [];
|
|
230
|
+
let cloned = [...list];
|
|
231
|
+
if (typeof sort === "function")
|
|
232
|
+
cloned = cloned.sort(sort);
|
|
233
|
+
else if (typeof sort === "string") {
|
|
234
|
+
cloned = cloned.sort(sortByDate(sort === "date-asc" ? "asc" : "desc"));
|
|
235
|
+
} else if (sort && typeof sort === "object" && sort.date) {
|
|
236
|
+
cloned = cloned.sort(sortByDate(sort.date === "asc" ? "asc" : "desc"));
|
|
237
|
+
}
|
|
238
|
+
if (typeof limit === "number" && limit >= 0)
|
|
239
|
+
cloned = cloned.slice(0, limit);
|
|
240
|
+
return cloned;
|
|
241
|
+
}, [index, collection, sort, limit]);
|
|
242
|
+
const prefetch = useCallback2((entry) => prefetchContent(entry), []);
|
|
243
|
+
return { items, prefetch };
|
|
244
|
+
}
|
|
245
|
+
// packages/react/src/hooks/useData.ts
|
|
246
|
+
import { useEffect as useEffect3, useMemo as useMemo4, useState as useState3 } from "react";
|
|
247
|
+
|
|
248
|
+
// packages/react/src/hooks/useRouter.tsx
|
|
249
|
+
import { useContext as useContext2 } from "react";
|
|
250
|
+
// packages/react/src/providers/RouterProvider.tsx
|
|
251
|
+
import React, {
|
|
252
|
+
createContext as createContext2,
|
|
253
|
+
useCallback as useCallback3,
|
|
254
|
+
useEffect as useEffect2,
|
|
255
|
+
useMemo as useMemo3,
|
|
256
|
+
useSyncExternalStore
|
|
257
|
+
} from "react";
|
|
258
|
+
import { flushSync } from "react-dom";
|
|
259
|
+
|
|
260
|
+
// packages/react/src/utils/head.ts
|
|
261
|
+
var HEAD_ATTR = "data-reroute-ssr-head";
|
|
262
|
+
var HEAD_ATTR_ROUTE = "data-reroute-route-head";
|
|
263
|
+
function isBrowser() {
|
|
264
|
+
return typeof document !== "undefined" && typeof window !== "undefined";
|
|
265
|
+
}
|
|
266
|
+
function applyPageMeta(meta) {
|
|
267
|
+
if (!isBrowser() || !meta || typeof meta !== "object")
|
|
268
|
+
return;
|
|
269
|
+
try {
|
|
270
|
+
const title = typeof meta.title === "string" ? meta.title : undefined;
|
|
271
|
+
const description = typeof meta.description === "string" ? meta.description : typeof meta.excerpt === "string" ? meta.excerpt : undefined;
|
|
272
|
+
if (title)
|
|
273
|
+
document.title = title;
|
|
274
|
+
if (description) {
|
|
275
|
+
let tag = document.head.querySelector('meta[name="description"]');
|
|
276
|
+
if (!tag) {
|
|
277
|
+
tag = document.createElement("meta");
|
|
278
|
+
tag.setAttribute("name", "description");
|
|
279
|
+
document.head.appendChild(tag);
|
|
280
|
+
}
|
|
281
|
+
tag.setAttribute("content", description);
|
|
282
|
+
}
|
|
283
|
+
} catch {}
|
|
284
|
+
}
|
|
285
|
+
function applyLang(lang) {
|
|
286
|
+
if (!isBrowser())
|
|
287
|
+
return;
|
|
288
|
+
if (typeof lang === "string" && lang.trim()) {
|
|
289
|
+
try {
|
|
290
|
+
document.documentElement.lang = lang.trim();
|
|
291
|
+
} catch {}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function applySsrHead(head) {
|
|
295
|
+
if (!isBrowser())
|
|
296
|
+
return;
|
|
297
|
+
try {
|
|
298
|
+
document.querySelectorAll(`[${HEAD_ATTR}]`).forEach((n) => {
|
|
299
|
+
n.parentElement?.removeChild(n);
|
|
300
|
+
});
|
|
301
|
+
if (!head)
|
|
302
|
+
return;
|
|
303
|
+
const parts = Array.isArray(head) ? head.map((x) => String(x)) : [String(head)];
|
|
304
|
+
const html = parts.map((p) => typeof p === "string" ? p : String(p)).join(`
|
|
305
|
+
`);
|
|
306
|
+
if (!html.trim())
|
|
307
|
+
return;
|
|
308
|
+
const tpl = document.createElement("template");
|
|
309
|
+
tpl.innerHTML = html;
|
|
310
|
+
const nodes = Array.from(tpl.content.childNodes);
|
|
311
|
+
for (const node of nodes) {
|
|
312
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
313
|
+
node.setAttribute(HEAD_ATTR, "");
|
|
314
|
+
document.head.appendChild(node);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
} catch {}
|
|
318
|
+
}
|
|
319
|
+
function applyRouteHead(head) {
|
|
320
|
+
if (!isBrowser())
|
|
321
|
+
return;
|
|
322
|
+
try {
|
|
323
|
+
document.querySelectorAll(`[${HEAD_ATTR_ROUTE}]`).forEach((n) => {
|
|
324
|
+
n.parentElement?.removeChild(n);
|
|
325
|
+
});
|
|
326
|
+
if (!head)
|
|
327
|
+
return;
|
|
328
|
+
const parts = Array.isArray(head) ? head.map((x) => String(x)) : [String(head)];
|
|
329
|
+
const html = parts.map((p) => typeof p === "string" ? p : String(p)).join(`
|
|
330
|
+
`);
|
|
331
|
+
if (!html.trim())
|
|
332
|
+
return;
|
|
333
|
+
const tpl = document.createElement("template");
|
|
334
|
+
tpl.innerHTML = html;
|
|
335
|
+
const nodes = Array.from(tpl.content.childNodes);
|
|
336
|
+
for (const node of nodes) {
|
|
337
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
338
|
+
node.setAttribute(HEAD_ATTR_ROUTE, "");
|
|
339
|
+
document.head.appendChild(node);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
} catch {}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// packages/react/src/providers/RouterProvider.tsx
|
|
346
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
347
|
+
var isBrowser2 = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
348
|
+
var OutletContext = createContext2(null);
|
|
349
|
+
var RouterContext = createContext2(null);
|
|
350
|
+
var listeners = [];
|
|
351
|
+
var currentLocation = isBrowser2 ? {
|
|
352
|
+
pathname: window.location.pathname,
|
|
353
|
+
search: window.location.search,
|
|
354
|
+
hash: window.location.hash
|
|
355
|
+
} : { pathname: "/", search: "", hash: "" };
|
|
356
|
+
function subscribe(listener) {
|
|
357
|
+
if (!isBrowser2)
|
|
358
|
+
return () => {};
|
|
359
|
+
listeners.push(listener);
|
|
360
|
+
return () => {
|
|
361
|
+
listeners = listeners.filter((l) => l !== listener);
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function getSnapshot() {
|
|
365
|
+
return currentLocation;
|
|
366
|
+
}
|
|
367
|
+
function emitChange() {
|
|
368
|
+
for (const listener of listeners) {
|
|
369
|
+
listener();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
var supportsViewTransitions = typeof document !== "undefined" && "startViewTransition" in document;
|
|
373
|
+
var viewTransitionsEnabled = false;
|
|
374
|
+
function setViewTransitionsEnabled(enabled) {
|
|
375
|
+
viewTransitionsEnabled = enabled && supportsViewTransitions;
|
|
376
|
+
}
|
|
377
|
+
var scrollRestorationEnabled = true;
|
|
378
|
+
function setScrollRestorationEnabled(enabled) {
|
|
379
|
+
scrollRestorationEnabled = enabled;
|
|
380
|
+
}
|
|
381
|
+
var scrollPositions = new Map;
|
|
382
|
+
function navigateInternal(to, options = {}) {
|
|
383
|
+
if (!isBrowser2)
|
|
384
|
+
return;
|
|
385
|
+
const url = new URL(to, window.location.origin);
|
|
386
|
+
if (url.origin !== window.location.origin) {
|
|
387
|
+
window.location.href = to;
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const newPath = url.pathname + url.search + url.hash;
|
|
391
|
+
const currentPath = window.location.pathname + window.location.search + window.location.hash;
|
|
392
|
+
if (newPath === currentPath)
|
|
393
|
+
return;
|
|
394
|
+
if (scrollRestorationEnabled) {
|
|
395
|
+
scrollPositions.set(currentPath, {
|
|
396
|
+
x: window.scrollX,
|
|
397
|
+
y: window.scrollY
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
if (options.replace) {
|
|
401
|
+
window.history.replaceState(options.state || null, "", to);
|
|
402
|
+
} else {
|
|
403
|
+
window.history.pushState(options.state || null, "", to);
|
|
404
|
+
}
|
|
405
|
+
const updateState = () => {
|
|
406
|
+
currentLocation = {
|
|
407
|
+
pathname: url.pathname,
|
|
408
|
+
search: url.search,
|
|
409
|
+
hash: url.hash
|
|
410
|
+
};
|
|
411
|
+
emitChange();
|
|
412
|
+
};
|
|
413
|
+
if (viewTransitionsEnabled) {
|
|
414
|
+
document.startViewTransition(() => {
|
|
415
|
+
flushSync(() => {
|
|
416
|
+
updateState();
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
} else {
|
|
420
|
+
updateState();
|
|
421
|
+
}
|
|
422
|
+
if (url.hash) {
|
|
423
|
+
const element = document.querySelector(url.hash);
|
|
424
|
+
if (element) {
|
|
425
|
+
element.scrollIntoView({ behavior: "smooth" });
|
|
426
|
+
}
|
|
427
|
+
} else {
|
|
428
|
+
window.scrollTo({ top: 0, behavior: "instant" });
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function RouterProvider({
|
|
432
|
+
children,
|
|
433
|
+
layouts = [],
|
|
434
|
+
matchRoute,
|
|
435
|
+
notFoundRoutes = [],
|
|
436
|
+
notFound: NotFound,
|
|
437
|
+
pathname = "/",
|
|
438
|
+
viewTransitions = true,
|
|
439
|
+
scrollRestoration = true
|
|
440
|
+
}) {
|
|
441
|
+
useEffect2(() => {
|
|
442
|
+
setViewTransitionsEnabled(viewTransitions);
|
|
443
|
+
setScrollRestorationEnabled(scrollRestoration);
|
|
444
|
+
}, [viewTransitions, scrollRestoration]);
|
|
445
|
+
const serverSnapshotRef = React.useRef(null);
|
|
446
|
+
if (!serverSnapshotRef.current) {
|
|
447
|
+
if (isBrowser2) {
|
|
448
|
+
serverSnapshotRef.current = currentLocation;
|
|
449
|
+
} else {
|
|
450
|
+
serverSnapshotRef.current = { pathname, search: "", hash: "" };
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
const getServerSnapshot = useCallback3(() => serverSnapshotRef.current, []);
|
|
454
|
+
const location = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) || currentLocation;
|
|
455
|
+
useEffect2(() => {
|
|
456
|
+
if (!isBrowser2)
|
|
457
|
+
return;
|
|
458
|
+
const next = {
|
|
459
|
+
pathname: window.location.pathname,
|
|
460
|
+
search: window.location.search,
|
|
461
|
+
hash: window.location.hash
|
|
462
|
+
};
|
|
463
|
+
if (currentLocation.pathname !== next.pathname || currentLocation.search !== next.search || currentLocation.hash !== next.hash) {
|
|
464
|
+
currentLocation = next;
|
|
465
|
+
emitChange();
|
|
466
|
+
}
|
|
467
|
+
}, []);
|
|
468
|
+
const target = useMemo3(() => matchRoute(location.pathname), [location.pathname, matchRoute]);
|
|
469
|
+
const params = target?.params || {};
|
|
470
|
+
const searchParams = useMemo3(() => new URLSearchParams(location.search), [location.search]);
|
|
471
|
+
const navigate = useCallback3((to, options = {}) => {
|
|
472
|
+
navigateInternal(to, options);
|
|
473
|
+
}, []);
|
|
474
|
+
useEffect2(() => {
|
|
475
|
+
if (!isBrowser2)
|
|
476
|
+
return;
|
|
477
|
+
const handlePopState = () => {
|
|
478
|
+
const next = {
|
|
479
|
+
pathname: window.location.pathname,
|
|
480
|
+
search: window.location.search,
|
|
481
|
+
hash: window.location.hash
|
|
482
|
+
};
|
|
483
|
+
try {
|
|
484
|
+
const w = window;
|
|
485
|
+
w.__REROUTE_DATA__ = w.__REROUTE_DATA__ || {};
|
|
486
|
+
const have = w.__REROUTE_DATA__[next.pathname];
|
|
487
|
+
const isDynamic = !!matchRoute?.(next.pathname)?.route?.isDynamic;
|
|
488
|
+
if (isDynamic && have === undefined) {
|
|
489
|
+
let updated = false;
|
|
490
|
+
const fallback = setTimeout(() => {
|
|
491
|
+
if (updated)
|
|
492
|
+
return;
|
|
493
|
+
updated = true;
|
|
494
|
+
currentLocation = next;
|
|
495
|
+
emitChange();
|
|
496
|
+
}, 250);
|
|
497
|
+
fetch(`/__reroute_data?path=${encodeURIComponent(next.pathname)}`, {
|
|
498
|
+
headers: { Accept: "application/json" },
|
|
499
|
+
credentials: "same-origin"
|
|
500
|
+
}).then((r) => r.ok ? r.json() : null).then((j) => {
|
|
501
|
+
try {
|
|
502
|
+
const payload = j ? j.data ?? j : undefined;
|
|
503
|
+
if (payload !== undefined)
|
|
504
|
+
w.__REROUTE_DATA__[next.pathname] = payload;
|
|
505
|
+
try {
|
|
506
|
+
w.dispatchEvent(new CustomEvent("__reroute_data__", {
|
|
507
|
+
detail: { key: next.pathname }
|
|
508
|
+
}));
|
|
509
|
+
} catch {}
|
|
510
|
+
} catch {}
|
|
511
|
+
}).catch(() => {}).finally(() => {
|
|
512
|
+
if (!updated) {
|
|
513
|
+
clearTimeout(fallback);
|
|
514
|
+
updated = true;
|
|
515
|
+
currentLocation = next;
|
|
516
|
+
emitChange();
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
} catch {}
|
|
522
|
+
const updateState = () => {
|
|
523
|
+
currentLocation = next;
|
|
524
|
+
emitChange();
|
|
525
|
+
};
|
|
526
|
+
if (viewTransitionsEnabled) {
|
|
527
|
+
document.startViewTransition(() => {
|
|
528
|
+
flushSync(() => {
|
|
529
|
+
updateState();
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
} else {
|
|
533
|
+
updateState();
|
|
534
|
+
}
|
|
535
|
+
if (scrollRestorationEnabled) {
|
|
536
|
+
const nextPath = next.pathname + next.search + next.hash;
|
|
537
|
+
const savedPosition = scrollPositions.get(nextPath);
|
|
538
|
+
setTimeout(() => {
|
|
539
|
+
if (next.hash) {
|
|
540
|
+
const element = document.querySelector(next.hash);
|
|
541
|
+
if (element) {
|
|
542
|
+
element.scrollIntoView({ behavior: "smooth" });
|
|
543
|
+
}
|
|
544
|
+
} else if (savedPosition) {
|
|
545
|
+
window.scrollTo({
|
|
546
|
+
top: savedPosition.y,
|
|
547
|
+
left: savedPosition.x,
|
|
548
|
+
behavior: "instant"
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
}, viewTransitionsEnabled ? 50 : 0);
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
window.addEventListener("popstate", handlePopState);
|
|
555
|
+
return () => window.removeEventListener("popstate", handlePopState);
|
|
556
|
+
}, [matchRoute]);
|
|
557
|
+
useEffect2(() => {
|
|
558
|
+
if (!isBrowser2)
|
|
559
|
+
return;
|
|
560
|
+
const handleClick = (e) => {
|
|
561
|
+
const target2 = e.target.closest("a");
|
|
562
|
+
if (!target2)
|
|
563
|
+
return;
|
|
564
|
+
const href = target2.getAttribute("href");
|
|
565
|
+
if (!href)
|
|
566
|
+
return;
|
|
567
|
+
if (target2.target === "_blank" || target2.hasAttribute("download") || e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const url = new URL(href, window.location.origin);
|
|
571
|
+
if (url.origin !== window.location.origin)
|
|
572
|
+
return;
|
|
573
|
+
const match = matchRoute(url.pathname);
|
|
574
|
+
if (!match)
|
|
575
|
+
return;
|
|
576
|
+
e.preventDefault();
|
|
577
|
+
navigate(href);
|
|
578
|
+
};
|
|
579
|
+
document.addEventListener("click", handleClick);
|
|
580
|
+
return () => document.removeEventListener("click", handleClick);
|
|
581
|
+
}, [navigate, matchRoute]);
|
|
582
|
+
useEffect2(() => {
|
|
583
|
+
const route = target?.route;
|
|
584
|
+
if (!route)
|
|
585
|
+
return;
|
|
586
|
+
try {
|
|
587
|
+
if (route.meta)
|
|
588
|
+
applyPageMeta(route.meta);
|
|
589
|
+
} catch {}
|
|
590
|
+
try {
|
|
591
|
+
const ssr = route.ssr;
|
|
592
|
+
if (ssr?.head)
|
|
593
|
+
applyRouteHead(ssr.head);
|
|
594
|
+
if (ssr?.lang)
|
|
595
|
+
applyLang(ssr.lang);
|
|
596
|
+
} catch {}
|
|
597
|
+
return () => {
|
|
598
|
+
applyRouteHead(undefined);
|
|
599
|
+
};
|
|
600
|
+
}, [target]);
|
|
601
|
+
const notFoundResolver = useCallback3((pathname2) => {
|
|
602
|
+
try {
|
|
603
|
+
const list = Array.isArray(notFoundRoutes) ? notFoundRoutes : [];
|
|
604
|
+
let chosen;
|
|
605
|
+
let bestLen = -1;
|
|
606
|
+
for (const nf of list) {
|
|
607
|
+
const pat = String(nf?.pattern || "/");
|
|
608
|
+
if (!pathname2.startsWith(pat))
|
|
609
|
+
continue;
|
|
610
|
+
const len = pat.split("/").filter(Boolean).length;
|
|
611
|
+
if (len >= bestLen) {
|
|
612
|
+
bestLen = len;
|
|
613
|
+
chosen = nf;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return chosen?.component;
|
|
617
|
+
} catch {
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
}, [notFoundRoutes]);
|
|
621
|
+
const contextValue = useMemo3(() => ({
|
|
622
|
+
pathname: location.pathname,
|
|
623
|
+
params,
|
|
624
|
+
searchParams,
|
|
625
|
+
navigate,
|
|
626
|
+
target,
|
|
627
|
+
matchRoute,
|
|
628
|
+
notFoundResolver
|
|
629
|
+
}), [
|
|
630
|
+
location.pathname,
|
|
631
|
+
params,
|
|
632
|
+
searchParams,
|
|
633
|
+
navigate,
|
|
634
|
+
target,
|
|
635
|
+
matchRoute,
|
|
636
|
+
notFoundResolver
|
|
637
|
+
]);
|
|
638
|
+
const matchingLayouts = useMemo3(() => {
|
|
639
|
+
return layouts.filter((layout) => {
|
|
640
|
+
if (layout.pattern === "/")
|
|
641
|
+
return true;
|
|
642
|
+
return location.pathname.startsWith(layout.pattern);
|
|
643
|
+
}).sort((a, b) => {
|
|
644
|
+
return b.pattern.split("/").length - a.pattern.split("/").length;
|
|
645
|
+
});
|
|
646
|
+
}, [layouts, location.pathname]);
|
|
647
|
+
let content;
|
|
648
|
+
if (target) {
|
|
649
|
+
const Component = target.route.component;
|
|
650
|
+
let outletContent = /* @__PURE__ */ jsxDEV2(Component, {}, undefined, false, undefined, this);
|
|
651
|
+
for (let i = matchingLayouts.length - 1;i >= 0; i--) {
|
|
652
|
+
const Layout = matchingLayouts[i].component;
|
|
653
|
+
const currentOutlet = outletContent;
|
|
654
|
+
outletContent = /* @__PURE__ */ jsxDEV2(OutletContext.Provider, {
|
|
655
|
+
value: currentOutlet,
|
|
656
|
+
children: /* @__PURE__ */ jsxDEV2(Layout, {}, undefined, false, undefined, this)
|
|
657
|
+
}, undefined, false, undefined, this);
|
|
658
|
+
}
|
|
659
|
+
content = outletContent;
|
|
660
|
+
} else {
|
|
661
|
+
const Fallback = notFoundResolver(location.pathname) || NotFound;
|
|
662
|
+
if (Fallback) {
|
|
663
|
+
content = /* @__PURE__ */ jsxDEV2(Fallback, {}, undefined, false, undefined, this);
|
|
664
|
+
} else {
|
|
665
|
+
content = /* @__PURE__ */ jsxDEV2("div", {
|
|
666
|
+
style: { padding: "2rem", textAlign: "center" },
|
|
667
|
+
children: [
|
|
668
|
+
/* @__PURE__ */ jsxDEV2("h1", {
|
|
669
|
+
children: "404 - Page Not Found"
|
|
670
|
+
}, undefined, false, undefined, this),
|
|
671
|
+
/* @__PURE__ */ jsxDEV2("p", {
|
|
672
|
+
children: [
|
|
673
|
+
"The page ",
|
|
674
|
+
location.pathname,
|
|
675
|
+
" could not be found."
|
|
676
|
+
]
|
|
677
|
+
}, undefined, true, undefined, this),
|
|
678
|
+
/* @__PURE__ */ jsxDEV2("a", {
|
|
679
|
+
href: "/",
|
|
680
|
+
children: "Go Home"
|
|
681
|
+
}, undefined, false, undefined, this)
|
|
682
|
+
]
|
|
683
|
+
}, undefined, true, undefined, this);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return /* @__PURE__ */ jsxDEV2(RouterContext.Provider, {
|
|
687
|
+
value: contextValue,
|
|
688
|
+
children: children || content
|
|
689
|
+
}, undefined, false, undefined, this);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// packages/react/src/providers/RerouteProvider.tsx
|
|
693
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
694
|
+
function RerouteProvider({
|
|
695
|
+
from,
|
|
696
|
+
children
|
|
697
|
+
}) {
|
|
698
|
+
const {
|
|
699
|
+
byCollection,
|
|
700
|
+
getContentEntry,
|
|
701
|
+
loadContent,
|
|
702
|
+
contentBaseUrl,
|
|
703
|
+
layouts = [],
|
|
704
|
+
matchRoute,
|
|
705
|
+
notFoundRoutes,
|
|
706
|
+
notFound,
|
|
707
|
+
pathname,
|
|
708
|
+
viewTransitions,
|
|
709
|
+
scrollRestoration
|
|
710
|
+
} = from;
|
|
711
|
+
const loader = loadContent || (contentBaseUrl ? (c) => import(`${contentBaseUrl}/${c}.js`) : undefined);
|
|
712
|
+
return /* @__PURE__ */ jsxDEV3(ContentProvider, {
|
|
713
|
+
getEntry: getContentEntry,
|
|
714
|
+
byCollection: byCollection || null,
|
|
715
|
+
loadCollection: loader,
|
|
716
|
+
children: /* @__PURE__ */ jsxDEV3(RouterProvider, {
|
|
717
|
+
layouts,
|
|
718
|
+
matchRoute,
|
|
719
|
+
notFoundRoutes,
|
|
720
|
+
notFound,
|
|
721
|
+
pathname,
|
|
722
|
+
viewTransitions,
|
|
723
|
+
scrollRestoration,
|
|
724
|
+
children
|
|
725
|
+
}, undefined, false, undefined, this)
|
|
726
|
+
}, undefined, false, undefined, this);
|
|
727
|
+
}
|
|
728
|
+
// packages/react/src/hooks/useRouter.tsx
|
|
729
|
+
function useRouter() {
|
|
730
|
+
const context = useContext2(RouterContext);
|
|
731
|
+
if (!context) {
|
|
732
|
+
throw new Error("useRouter must be used within a RouterProvider");
|
|
733
|
+
}
|
|
734
|
+
return context;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// packages/react/src/hooks/useData.ts
|
|
738
|
+
function useData(key) {
|
|
739
|
+
const { pathname } = useRouter();
|
|
740
|
+
const k = key || pathname;
|
|
741
|
+
const [_tick, setTick] = useState3(0);
|
|
742
|
+
useEffect3(() => {
|
|
743
|
+
if (typeof window === "undefined")
|
|
744
|
+
return;
|
|
745
|
+
const handler = (e) => {
|
|
746
|
+
try {
|
|
747
|
+
const detail = e.detail;
|
|
748
|
+
if (detail?.key && detail.key !== k)
|
|
749
|
+
return;
|
|
750
|
+
setTick((x) => x + 1);
|
|
751
|
+
} catch {}
|
|
752
|
+
};
|
|
753
|
+
window.addEventListener("__reroute_data__", handler);
|
|
754
|
+
return () => {
|
|
755
|
+
try {
|
|
756
|
+
window.removeEventListener("__reroute_data__", handler);
|
|
757
|
+
} catch {}
|
|
758
|
+
};
|
|
759
|
+
}, [k]);
|
|
760
|
+
useEffect3(() => {
|
|
761
|
+
if (typeof window === "undefined")
|
|
762
|
+
return;
|
|
763
|
+
try {
|
|
764
|
+
const w = window;
|
|
765
|
+
w.__REROUTE_DATA__ = w.__REROUTE_DATA__ || {};
|
|
766
|
+
if (w.__REROUTE_DATA__[k] !== undefined)
|
|
767
|
+
return;
|
|
768
|
+
w.__REROUTE_DATA_PENDING__ = w.__REROUTE_DATA_PENDING__ || {};
|
|
769
|
+
const pending = w.__REROUTE_DATA_PENDING__;
|
|
770
|
+
if (pending[k])
|
|
771
|
+
return;
|
|
772
|
+
pending[k] = true;
|
|
773
|
+
fetch(`/__reroute_data?path=${encodeURIComponent(k)}`, {
|
|
774
|
+
headers: { Accept: "application/json" },
|
|
775
|
+
credentials: "same-origin"
|
|
776
|
+
}).then((r) => r.ok ? r.json() : null).then((j) => {
|
|
777
|
+
if (!j)
|
|
778
|
+
return;
|
|
779
|
+
w.__REROUTE_DATA__[k] = j.data ?? j;
|
|
780
|
+
try {
|
|
781
|
+
setTick((x) => x + 1);
|
|
782
|
+
} catch {}
|
|
783
|
+
try {
|
|
784
|
+
w.dispatchEvent(new CustomEvent("__reroute_data__", {
|
|
785
|
+
detail: { key: k }
|
|
786
|
+
}));
|
|
787
|
+
} catch {}
|
|
788
|
+
}).catch(() => {}).finally(() => {
|
|
789
|
+
try {
|
|
790
|
+
delete w.__REROUTE_DATA_PENDING__[k];
|
|
791
|
+
} catch {}
|
|
792
|
+
});
|
|
793
|
+
} catch {}
|
|
794
|
+
}, [k]);
|
|
795
|
+
return useMemo4(() => {
|
|
796
|
+
try {
|
|
797
|
+
if (typeof window === "undefined") {
|
|
798
|
+
const g = globalThis;
|
|
799
|
+
return g.__REROUTE_DATA__?.[k];
|
|
800
|
+
}
|
|
801
|
+
const w = window;
|
|
802
|
+
return w.__REROUTE_DATA__?.[k];
|
|
803
|
+
} catch {
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
}, [k]);
|
|
807
|
+
}
|
|
808
|
+
// packages/react/src/hooks/useNavigate.tsx
|
|
809
|
+
function useNavigate() {
|
|
810
|
+
const { navigate } = useRouter();
|
|
811
|
+
return navigate;
|
|
812
|
+
}
|
|
813
|
+
// packages/react/src/hooks/useParams.tsx
|
|
814
|
+
function useParams() {
|
|
815
|
+
const { params } = useRouter();
|
|
816
|
+
return params;
|
|
817
|
+
}
|
|
818
|
+
// packages/react/src/hooks/useSearchParams.tsx
|
|
819
|
+
function useSearchParams() {
|
|
820
|
+
const { searchParams } = useRouter();
|
|
821
|
+
return searchParams;
|
|
822
|
+
}
|
|
823
|
+
// packages/react/src/components/ContentRoute.tsx
|
|
824
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
825
|
+
function toComponent(x) {
|
|
826
|
+
if (typeof x === "function")
|
|
827
|
+
return x;
|
|
828
|
+
if (isValidElement(x))
|
|
829
|
+
return () => x;
|
|
830
|
+
return () => null;
|
|
831
|
+
}
|
|
832
|
+
function ContentRoute({
|
|
833
|
+
collection,
|
|
834
|
+
name,
|
|
835
|
+
getEntry
|
|
836
|
+
}) {
|
|
837
|
+
const params = useParams();
|
|
838
|
+
const { pathname, notFoundResolver } = useRouter();
|
|
839
|
+
const inferredName = name || params.slug || params.name || (() => {
|
|
840
|
+
try {
|
|
841
|
+
const parts = String(pathname || "").split("/").filter(Boolean);
|
|
842
|
+
return parts.length >= 2 ? parts[1] : undefined;
|
|
843
|
+
} catch {
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
})();
|
|
847
|
+
const key = inferredName ? `${collection}:${inferredName}` : `${collection}:`;
|
|
848
|
+
const ctxGetEntry = useContentGetEntry();
|
|
849
|
+
const idx = useContentIndex();
|
|
850
|
+
const resolveEntry = getEntry || ctxGetEntry || ((c, n) => {
|
|
851
|
+
try {
|
|
852
|
+
const list = idx?.[c];
|
|
853
|
+
if (!Array.isArray(list))
|
|
854
|
+
return;
|
|
855
|
+
const found = list.find((e) => e?.name === n);
|
|
856
|
+
if (!found)
|
|
857
|
+
return;
|
|
858
|
+
return { module: found.module, meta: found.meta };
|
|
859
|
+
} catch {
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
const entry = inferredName && resolveEntry ? resolveEntry(collection, inferredName) : undefined;
|
|
864
|
+
const initialComp = useMemo5(() => {
|
|
865
|
+
try {
|
|
866
|
+
const g = globalThis;
|
|
867
|
+
const C = g.__REROUTE_SSR_MODULES__?.[key];
|
|
868
|
+
if (C)
|
|
869
|
+
return toComponent(C);
|
|
870
|
+
} catch {}
|
|
871
|
+
if (typeof window !== "undefined") {
|
|
872
|
+
const store = window.__REROUTE_MODULES__ || {};
|
|
873
|
+
if (store[key])
|
|
874
|
+
return toComponent(store[key]);
|
|
875
|
+
}
|
|
876
|
+
if (entry?.component)
|
|
877
|
+
return toComponent(entry.component);
|
|
878
|
+
try {
|
|
879
|
+
const nf = typeof notFoundResolver === "function" ? notFoundResolver(pathname) : undefined;
|
|
880
|
+
if (nf)
|
|
881
|
+
return toComponent(nf);
|
|
882
|
+
} catch {}
|
|
883
|
+
return () => null;
|
|
884
|
+
}, [key, entry]);
|
|
885
|
+
const [Comp, setComp] = useState4(() => initialComp);
|
|
886
|
+
useEffect4(() => {
|
|
887
|
+
let cancelled = false;
|
|
888
|
+
if (entry?.module && typeof window !== "undefined") {
|
|
889
|
+
import(entry.module).then((m) => {
|
|
890
|
+
if (cancelled)
|
|
891
|
+
return;
|
|
892
|
+
const C = m.default || m;
|
|
893
|
+
const K = toComponent(C);
|
|
894
|
+
setComp(() => K);
|
|
895
|
+
const w = window;
|
|
896
|
+
w.__REROUTE_MODULES__ ||= {};
|
|
897
|
+
w.__REROUTE_MODULES__[key] = C;
|
|
898
|
+
try {
|
|
899
|
+
const meta = m.meta || m.frontmatter;
|
|
900
|
+
if (meta)
|
|
901
|
+
applyPageMeta(meta);
|
|
902
|
+
} catch {}
|
|
903
|
+
try {
|
|
904
|
+
const ssr = m.ssr;
|
|
905
|
+
if (ssr?.head)
|
|
906
|
+
applySsrHead(ssr.head);
|
|
907
|
+
if (ssr?.lang)
|
|
908
|
+
applyLang(ssr.lang);
|
|
909
|
+
} catch {}
|
|
910
|
+
}).catch(() => {});
|
|
911
|
+
}
|
|
912
|
+
return () => {
|
|
913
|
+
cancelled = true;
|
|
914
|
+
applySsrHead(undefined);
|
|
915
|
+
};
|
|
916
|
+
}, [entry?.module, key]);
|
|
917
|
+
useEffect4(() => {
|
|
918
|
+
try {
|
|
919
|
+
if (entry && entry.meta)
|
|
920
|
+
applyPageMeta(entry.meta);
|
|
921
|
+
} catch {}
|
|
922
|
+
}, [entry]);
|
|
923
|
+
return /* @__PURE__ */ jsxDEV4(Comp, {}, undefined, false, undefined, this);
|
|
924
|
+
}
|
|
925
|
+
// packages/react/src/components/Link.tsx
|
|
926
|
+
import { useCallback as useCallback4, useMemo as useMemo6 } from "react";
|
|
927
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
928
|
+
function Link({
|
|
929
|
+
to,
|
|
930
|
+
replace,
|
|
931
|
+
state,
|
|
932
|
+
prefetch = true,
|
|
933
|
+
onClick,
|
|
934
|
+
onMouseEnter,
|
|
935
|
+
onFocus,
|
|
936
|
+
...props
|
|
937
|
+
}) {
|
|
938
|
+
const { navigate, matchRoute } = useRouter();
|
|
939
|
+
const resolver = useContentResolver();
|
|
940
|
+
const contentIndex = useContentIndex();
|
|
941
|
+
const ensureCollection = useContentLoadCollection();
|
|
942
|
+
const inferred = useMemo6(() => resolver ? resolver(String(to)) : undefined, [resolver, to]);
|
|
943
|
+
const handleClick = useCallback4(async (e) => {
|
|
944
|
+
if (onClick) {
|
|
945
|
+
onClick(e);
|
|
946
|
+
}
|
|
947
|
+
if (e.defaultPrevented || e.button !== 0 || e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || props.target === "_blank") {
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
e.preventDefault();
|
|
951
|
+
if (prefetch) {
|
|
952
|
+
try {
|
|
953
|
+
if (typeof window !== "undefined") {
|
|
954
|
+
const url = new URL(String(to), window.location.origin);
|
|
955
|
+
if (url.origin === window.location.origin) {
|
|
956
|
+
const path = url.pathname;
|
|
957
|
+
const isDynamic = !!matchRoute?.(path)?.route?.isDynamic;
|
|
958
|
+
const w = window;
|
|
959
|
+
w.__REROUTE_DATA__ = w.__REROUTE_DATA__ || {};
|
|
960
|
+
if (isDynamic && (!inferred || !inferred.module) && w.__REROUTE_DATA__[path] === undefined) {
|
|
961
|
+
const ctl = new AbortController;
|
|
962
|
+
const timer = setTimeout(() => ctl.abort(), 350);
|
|
963
|
+
try {
|
|
964
|
+
const r = await fetch(`/__reroute_data?path=${encodeURIComponent(path)}`, {
|
|
965
|
+
headers: { Accept: "application/json" },
|
|
966
|
+
credentials: "same-origin",
|
|
967
|
+
signal: ctl.signal
|
|
968
|
+
}).catch(() => null);
|
|
969
|
+
if (r?.ok) {
|
|
970
|
+
const j = await r.json().catch(() => null);
|
|
971
|
+
if (j) {
|
|
972
|
+
w.__REROUTE_DATA__[path] = j.data ?? j;
|
|
973
|
+
try {
|
|
974
|
+
w.dispatchEvent(new CustomEvent("__reroute_data__", {
|
|
975
|
+
detail: { key: path }
|
|
976
|
+
}));
|
|
977
|
+
} catch {}
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
} catch {}
|
|
981
|
+
clearTimeout(timer);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
} catch {}
|
|
986
|
+
}
|
|
987
|
+
navigate(to, { replace, state });
|
|
988
|
+
}, [
|
|
989
|
+
navigate,
|
|
990
|
+
to,
|
|
991
|
+
replace,
|
|
992
|
+
state,
|
|
993
|
+
onClick,
|
|
994
|
+
props.target,
|
|
995
|
+
prefetch,
|
|
996
|
+
inferred,
|
|
997
|
+
matchRoute
|
|
998
|
+
]);
|
|
999
|
+
const handleMouseEnter = useCallback4((e) => {
|
|
1000
|
+
if (prefetch && inferred && inferred.module)
|
|
1001
|
+
prefetchContent(inferred);
|
|
1002
|
+
else if (prefetch) {
|
|
1003
|
+
try {
|
|
1004
|
+
if (typeof window !== "undefined") {
|
|
1005
|
+
const url = new URL(String(to), window.location.origin);
|
|
1006
|
+
if (url.origin === window.location.origin) {
|
|
1007
|
+
const path = url.pathname;
|
|
1008
|
+
const isDynamic = !!matchRoute?.(path)?.route?.isDynamic;
|
|
1009
|
+
const known = !!(contentIndex && inferred && (inferred.collection in contentIndex));
|
|
1010
|
+
if (inferred && !inferred.module && ensureCollection && known) {
|
|
1011
|
+
(async () => {
|
|
1012
|
+
try {
|
|
1013
|
+
const items = await ensureCollection(inferred.collection);
|
|
1014
|
+
const found = (items || []).find((e2) => e2?.name === inferred.name);
|
|
1015
|
+
const mod = found?.module;
|
|
1016
|
+
if (mod)
|
|
1017
|
+
prefetchContent({ ...inferred, module: mod });
|
|
1018
|
+
} catch {}
|
|
1019
|
+
})();
|
|
1020
|
+
}
|
|
1021
|
+
const w = window;
|
|
1022
|
+
w.__REROUTE_DATA__ = w.__REROUTE_DATA__ || {};
|
|
1023
|
+
if (isDynamic && (!inferred || !inferred.module) && w.__REROUTE_DATA__[path] === undefined) {
|
|
1024
|
+
fetch(`/__reroute_data?path=${encodeURIComponent(path)}`, {
|
|
1025
|
+
headers: { Accept: "application/json" },
|
|
1026
|
+
credentials: "same-origin"
|
|
1027
|
+
}).then((r) => r.ok ? r.json() : null).then((j) => {
|
|
1028
|
+
if (!j)
|
|
1029
|
+
return;
|
|
1030
|
+
w.__REROUTE_DATA__[path] = j.data ?? j;
|
|
1031
|
+
try {
|
|
1032
|
+
w.dispatchEvent(new CustomEvent("__reroute_data__", {
|
|
1033
|
+
detail: { key: path }
|
|
1034
|
+
}));
|
|
1035
|
+
} catch {}
|
|
1036
|
+
}).catch(() => {});
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
} catch {}
|
|
1041
|
+
}
|
|
1042
|
+
if (onMouseEnter)
|
|
1043
|
+
onMouseEnter(e);
|
|
1044
|
+
}, [
|
|
1045
|
+
prefetch,
|
|
1046
|
+
inferred,
|
|
1047
|
+
onMouseEnter,
|
|
1048
|
+
to,
|
|
1049
|
+
contentIndex,
|
|
1050
|
+
ensureCollection,
|
|
1051
|
+
matchRoute
|
|
1052
|
+
]);
|
|
1053
|
+
const handleFocus = useCallback4((e) => {
|
|
1054
|
+
if (prefetch && inferred && inferred.module)
|
|
1055
|
+
prefetchContent(inferred);
|
|
1056
|
+
else if (prefetch) {
|
|
1057
|
+
try {
|
|
1058
|
+
if (typeof window !== "undefined") {
|
|
1059
|
+
const url = new URL(String(to), window.location.origin);
|
|
1060
|
+
if (url.origin === window.location.origin) {
|
|
1061
|
+
const path = url.pathname;
|
|
1062
|
+
const isDynamic = !!matchRoute?.(path)?.route?.isDynamic;
|
|
1063
|
+
const known2 = !!(contentIndex && inferred && (inferred.collection in contentIndex));
|
|
1064
|
+
if (inferred && !inferred.module && ensureCollection && known2) {
|
|
1065
|
+
(async () => {
|
|
1066
|
+
try {
|
|
1067
|
+
const items = await ensureCollection(inferred.collection);
|
|
1068
|
+
const found = (items || []).find((e2) => e2?.name === inferred.name);
|
|
1069
|
+
const mod = found?.module;
|
|
1070
|
+
if (mod)
|
|
1071
|
+
prefetchContent({ ...inferred, module: mod });
|
|
1072
|
+
} catch {}
|
|
1073
|
+
})();
|
|
1074
|
+
}
|
|
1075
|
+
const w = window;
|
|
1076
|
+
w.__REROUTE_DATA__ = w.__REROUTE_DATA__ || {};
|
|
1077
|
+
if (isDynamic && (!inferred || !inferred.module) && w.__REROUTE_DATA__[path] === undefined) {
|
|
1078
|
+
fetch(`/__reroute_data?path=${encodeURIComponent(path)}`, {
|
|
1079
|
+
headers: { Accept: "application/json" },
|
|
1080
|
+
credentials: "same-origin"
|
|
1081
|
+
}).then((r) => r.ok ? r.json() : null).then((j) => {
|
|
1082
|
+
if (!j)
|
|
1083
|
+
return;
|
|
1084
|
+
w.__REROUTE_DATA__[path] = j.data ?? j;
|
|
1085
|
+
try {
|
|
1086
|
+
w.dispatchEvent(new CustomEvent("__reroute_data__", {
|
|
1087
|
+
detail: { key: path }
|
|
1088
|
+
}));
|
|
1089
|
+
} catch {}
|
|
1090
|
+
}).catch(() => {});
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
} catch {}
|
|
1095
|
+
}
|
|
1096
|
+
if (onFocus)
|
|
1097
|
+
onFocus(e);
|
|
1098
|
+
}, [
|
|
1099
|
+
prefetch,
|
|
1100
|
+
inferred,
|
|
1101
|
+
onFocus,
|
|
1102
|
+
to,
|
|
1103
|
+
contentIndex,
|
|
1104
|
+
ensureCollection,
|
|
1105
|
+
matchRoute
|
|
1106
|
+
]);
|
|
1107
|
+
return /* @__PURE__ */ jsxDEV5("a", {
|
|
1108
|
+
href: to,
|
|
1109
|
+
onClick: handleClick,
|
|
1110
|
+
onMouseEnter: handleMouseEnter,
|
|
1111
|
+
onFocus: handleFocus,
|
|
1112
|
+
...props
|
|
1113
|
+
}, undefined, false, undefined, this);
|
|
1114
|
+
}
|
|
1115
|
+
// packages/react/src/components/Outlet.tsx
|
|
1116
|
+
import { useContext as useContext3 } from "react";
|
|
1117
|
+
import { jsxDEV as jsxDEV6, Fragment } from "react/jsx-dev-runtime";
|
|
1118
|
+
function Outlet() {
|
|
1119
|
+
const outletContent = useContext3(OutletContext);
|
|
1120
|
+
return /* @__PURE__ */ jsxDEV6(Fragment, {
|
|
1121
|
+
children: outletContent
|
|
1122
|
+
}, undefined, false, undefined, this);
|
|
1123
|
+
}
|
|
1124
|
+
export {
|
|
1125
|
+
useSearchParams,
|
|
1126
|
+
useRouter,
|
|
1127
|
+
useParams,
|
|
1128
|
+
useNavigate,
|
|
1129
|
+
useData,
|
|
1130
|
+
useContentResolver,
|
|
1131
|
+
useContentLoadCollection,
|
|
1132
|
+
useContentIndex,
|
|
1133
|
+
useContentGetEntry,
|
|
1134
|
+
useContent,
|
|
1135
|
+
prefetchContent,
|
|
1136
|
+
parseContentHref,
|
|
1137
|
+
createResolverFromGetEntry,
|
|
1138
|
+
applySsrHead,
|
|
1139
|
+
applyRouteHead,
|
|
1140
|
+
applyPageMeta,
|
|
1141
|
+
applyLang,
|
|
1142
|
+
RouterProvider,
|
|
1143
|
+
RouterContext,
|
|
1144
|
+
RerouteProvider,
|
|
1145
|
+
OutletContext,
|
|
1146
|
+
Outlet,
|
|
1147
|
+
Link,
|
|
1148
|
+
ContentRoute,
|
|
1149
|
+
ContentProvider
|
|
1150
|
+
};
|
|
1151
|
+
|
|
1152
|
+
//# debugId=BD66EE46EA6F55AE64756E2164756E21
|