@lolyjs/core 0.2.0-alpha.14 → 0.2.0-alpha.16
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 +1016 -755
- package/dist/{bootstrap-DgvWWDim.d.mts → bootstrap-BfGTMUkj.d.mts} +12 -0
- package/dist/{bootstrap-DgvWWDim.d.ts → bootstrap-BfGTMUkj.d.ts} +12 -0
- package/dist/cli.cjs +4389 -2972
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +4385 -2968
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +2225 -560
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +9 -75
- package/dist/index.d.ts +9 -75
- package/dist/index.js +2226 -561
- package/dist/index.js.map +1 -1
- package/dist/index.types-BPX6IVAC.d.mts +198 -0
- package/dist/index.types-BPX6IVAC.d.ts +198 -0
- package/dist/react/cache.cjs.map +1 -1
- package/dist/react/cache.d.mts +22 -2
- package/dist/react/cache.d.ts +22 -2
- package/dist/react/cache.js.map +1 -1
- package/dist/react/components.cjs.map +1 -1
- package/dist/react/components.js.map +1 -1
- package/dist/react/hooks.cjs.map +1 -1
- package/dist/react/hooks.js.map +1 -1
- package/dist/react/sockets.cjs.map +1 -1
- package/dist/react/sockets.js.map +1 -1
- package/dist/runtime.cjs +359 -95
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +359 -95
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime.cjs
CHANGED
|
@@ -111,22 +111,158 @@ function matchRouteClient(pathWithSearch, routes) {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
// modules/runtime/client/metadata.ts
|
|
114
|
+
function getOrCreateMeta(selector, attributes) {
|
|
115
|
+
let meta = document.querySelector(selector);
|
|
116
|
+
if (!meta) {
|
|
117
|
+
meta = document.createElement("meta");
|
|
118
|
+
if (attributes.name) meta.name = attributes.name;
|
|
119
|
+
if (attributes.property) meta.setAttribute("property", attributes.property);
|
|
120
|
+
if (attributes.httpEquiv) meta.httpEquiv = attributes.httpEquiv;
|
|
121
|
+
document.head.appendChild(meta);
|
|
122
|
+
}
|
|
123
|
+
return meta;
|
|
124
|
+
}
|
|
125
|
+
function getOrCreateLink(rel, href) {
|
|
126
|
+
const selector = `link[rel="${rel}"]`;
|
|
127
|
+
let link = document.querySelector(selector);
|
|
128
|
+
if (!link) {
|
|
129
|
+
link = document.createElement("link");
|
|
130
|
+
link.rel = rel;
|
|
131
|
+
link.href = href;
|
|
132
|
+
document.head.appendChild(link);
|
|
133
|
+
} else {
|
|
134
|
+
link.href = href;
|
|
135
|
+
}
|
|
136
|
+
return link;
|
|
137
|
+
}
|
|
114
138
|
function applyMetadata(md) {
|
|
115
139
|
if (!md) return;
|
|
116
140
|
if (md.title) {
|
|
117
141
|
document.title = md.title;
|
|
118
142
|
}
|
|
119
143
|
if (md.description) {
|
|
120
|
-
|
|
121
|
-
'meta[name="description"]'
|
|
122
|
-
);
|
|
123
|
-
if (!meta) {
|
|
124
|
-
meta = document.createElement("meta");
|
|
125
|
-
meta.name = "description";
|
|
126
|
-
document.head.appendChild(meta);
|
|
127
|
-
}
|
|
144
|
+
const meta = getOrCreateMeta('meta[name="description"]', { name: "description" });
|
|
128
145
|
meta.content = md.description;
|
|
129
146
|
}
|
|
147
|
+
if (md.robots) {
|
|
148
|
+
const meta = getOrCreateMeta('meta[name="robots"]', { name: "robots" });
|
|
149
|
+
meta.content = md.robots;
|
|
150
|
+
}
|
|
151
|
+
if (md.themeColor) {
|
|
152
|
+
const meta = getOrCreateMeta('meta[name="theme-color"]', { name: "theme-color" });
|
|
153
|
+
meta.content = md.themeColor;
|
|
154
|
+
}
|
|
155
|
+
if (md.viewport) {
|
|
156
|
+
const meta = getOrCreateMeta('meta[name="viewport"]', { name: "viewport" });
|
|
157
|
+
meta.content = md.viewport;
|
|
158
|
+
}
|
|
159
|
+
if (md.canonical) {
|
|
160
|
+
getOrCreateLink("canonical", md.canonical);
|
|
161
|
+
}
|
|
162
|
+
if (md.openGraph) {
|
|
163
|
+
const og = md.openGraph;
|
|
164
|
+
if (og.title) {
|
|
165
|
+
const meta = getOrCreateMeta('meta[property="og:title"]', { property: "og:title" });
|
|
166
|
+
meta.content = og.title;
|
|
167
|
+
}
|
|
168
|
+
if (og.description) {
|
|
169
|
+
const meta = getOrCreateMeta('meta[property="og:description"]', { property: "og:description" });
|
|
170
|
+
meta.content = og.description;
|
|
171
|
+
}
|
|
172
|
+
if (og.type) {
|
|
173
|
+
const meta = getOrCreateMeta('meta[property="og:type"]', { property: "og:type" });
|
|
174
|
+
meta.content = og.type;
|
|
175
|
+
}
|
|
176
|
+
if (og.url) {
|
|
177
|
+
const meta = getOrCreateMeta('meta[property="og:url"]', { property: "og:url" });
|
|
178
|
+
meta.content = og.url;
|
|
179
|
+
}
|
|
180
|
+
if (og.image) {
|
|
181
|
+
if (typeof og.image === "string") {
|
|
182
|
+
const meta = getOrCreateMeta('meta[property="og:image"]', { property: "og:image" });
|
|
183
|
+
meta.content = og.image;
|
|
184
|
+
} else {
|
|
185
|
+
const meta = getOrCreateMeta('meta[property="og:image"]', { property: "og:image" });
|
|
186
|
+
meta.content = og.image.url;
|
|
187
|
+
if (og.image.width) {
|
|
188
|
+
const metaWidth = getOrCreateMeta('meta[property="og:image:width"]', { property: "og:image:width" });
|
|
189
|
+
metaWidth.content = String(og.image.width);
|
|
190
|
+
}
|
|
191
|
+
if (og.image.height) {
|
|
192
|
+
const metaHeight = getOrCreateMeta('meta[property="og:image:height"]', { property: "og:image:height" });
|
|
193
|
+
metaHeight.content = String(og.image.height);
|
|
194
|
+
}
|
|
195
|
+
if (og.image.alt) {
|
|
196
|
+
const metaAlt = getOrCreateMeta('meta[property="og:image:alt"]', { property: "og:image:alt" });
|
|
197
|
+
metaAlt.content = og.image.alt;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (og.siteName) {
|
|
202
|
+
const meta = getOrCreateMeta('meta[property="og:site_name"]', { property: "og:site_name" });
|
|
203
|
+
meta.content = og.siteName;
|
|
204
|
+
}
|
|
205
|
+
if (og.locale) {
|
|
206
|
+
const meta = getOrCreateMeta('meta[property="og:locale"]', { property: "og:locale" });
|
|
207
|
+
meta.content = og.locale;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (md.twitter) {
|
|
211
|
+
const twitter = md.twitter;
|
|
212
|
+
if (twitter.card) {
|
|
213
|
+
const meta = getOrCreateMeta('meta[name="twitter:card"]', { name: "twitter:card" });
|
|
214
|
+
meta.content = twitter.card;
|
|
215
|
+
}
|
|
216
|
+
if (twitter.title) {
|
|
217
|
+
const meta = getOrCreateMeta('meta[name="twitter:title"]', { name: "twitter:title" });
|
|
218
|
+
meta.content = twitter.title;
|
|
219
|
+
}
|
|
220
|
+
if (twitter.description) {
|
|
221
|
+
const meta = getOrCreateMeta('meta[name="twitter:description"]', { name: "twitter:description" });
|
|
222
|
+
meta.content = twitter.description;
|
|
223
|
+
}
|
|
224
|
+
if (twitter.image) {
|
|
225
|
+
const meta = getOrCreateMeta('meta[name="twitter:image"]', { name: "twitter:image" });
|
|
226
|
+
meta.content = twitter.image;
|
|
227
|
+
}
|
|
228
|
+
if (twitter.imageAlt) {
|
|
229
|
+
const meta = getOrCreateMeta('meta[name="twitter:image:alt"]', { name: "twitter:image:alt" });
|
|
230
|
+
meta.content = twitter.imageAlt;
|
|
231
|
+
}
|
|
232
|
+
if (twitter.site) {
|
|
233
|
+
const meta = getOrCreateMeta('meta[name="twitter:site"]', { name: "twitter:site" });
|
|
234
|
+
meta.content = twitter.site;
|
|
235
|
+
}
|
|
236
|
+
if (twitter.creator) {
|
|
237
|
+
const meta = getOrCreateMeta('meta[name="twitter:creator"]', { name: "twitter:creator" });
|
|
238
|
+
meta.content = twitter.creator;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (md.metaTags && Array.isArray(md.metaTags)) {
|
|
242
|
+
md.metaTags.forEach((tag) => {
|
|
243
|
+
let selector = "";
|
|
244
|
+
if (tag.name) {
|
|
245
|
+
selector = `meta[name="${tag.name}"]`;
|
|
246
|
+
} else if (tag.property) {
|
|
247
|
+
selector = `meta[property="${tag.property}"]`;
|
|
248
|
+
} else if (tag.httpEquiv) {
|
|
249
|
+
selector = `meta[http-equiv="${tag.httpEquiv}"]`;
|
|
250
|
+
}
|
|
251
|
+
if (selector) {
|
|
252
|
+
const meta = getOrCreateMeta(selector, {
|
|
253
|
+
name: tag.name,
|
|
254
|
+
property: tag.property,
|
|
255
|
+
httpEquiv: tag.httpEquiv
|
|
256
|
+
});
|
|
257
|
+
meta.content = tag.content;
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
if (md.links && Array.isArray(md.links)) {
|
|
262
|
+
md.links.forEach((link) => {
|
|
263
|
+
getOrCreateLink(link.rel, link.href);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
130
266
|
}
|
|
131
267
|
|
|
132
268
|
// modules/runtime/client/AppShell.tsx
|
|
@@ -343,10 +479,15 @@ async function handleErrorRoute(nextUrl, json, errorRoute, setState) {
|
|
|
343
479
|
});
|
|
344
480
|
return true;
|
|
345
481
|
} catch (loadError) {
|
|
346
|
-
console.error(
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
482
|
+
console.error("\n\u274C [client] Error loading error route components:");
|
|
483
|
+
console.error(loadError);
|
|
484
|
+
if (loadError instanceof Error) {
|
|
485
|
+
console.error(` Message: ${loadError.message}`);
|
|
486
|
+
if (loadError.stack) {
|
|
487
|
+
console.error(` Stack: ${loadError.stack.split("\n").slice(0, 3).join("\n ")}`);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
console.error("\u{1F4A1} Falling back to full page reload\n");
|
|
350
491
|
window.location.href = nextUrl;
|
|
351
492
|
return false;
|
|
352
493
|
}
|
|
@@ -451,7 +592,11 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
451
592
|
searchParams: Object.fromEntries(url.searchParams.entries())
|
|
452
593
|
};
|
|
453
594
|
setRouterData(routerData);
|
|
454
|
-
const
|
|
595
|
+
const prefetched = prefetchedRoutes.get(matched.route);
|
|
596
|
+
const components = prefetched ? await prefetched : await matched.route.load();
|
|
597
|
+
if (!prefetched) {
|
|
598
|
+
prefetchedRoutes.set(matched.route, Promise.resolve(components));
|
|
599
|
+
}
|
|
455
600
|
window.scrollTo({
|
|
456
601
|
top: 0,
|
|
457
602
|
behavior: "smooth"
|
|
@@ -490,7 +635,7 @@ async function navigate(nextUrl, handlers, options) {
|
|
|
490
635
|
}
|
|
491
636
|
}
|
|
492
637
|
if (!ok) {
|
|
493
|
-
if (json
|
|
638
|
+
if (json?.redirect) {
|
|
494
639
|
window.location.href = json.redirect.destination;
|
|
495
640
|
return;
|
|
496
641
|
}
|
|
@@ -511,6 +656,47 @@ async function navigate(nextUrl, handlers, options) {
|
|
|
511
656
|
window.location.href = nextUrl;
|
|
512
657
|
}
|
|
513
658
|
}
|
|
659
|
+
var prefetchedRoutes = /* @__PURE__ */ new WeakMap();
|
|
660
|
+
function prefetchRoute(url, routes, notFoundRoute) {
|
|
661
|
+
const [pathname] = url.split("?");
|
|
662
|
+
const matched = matchRouteClient(pathname, routes);
|
|
663
|
+
if (!matched) {
|
|
664
|
+
if (notFoundRoute) {
|
|
665
|
+
const existing2 = prefetchedRoutes.get(notFoundRoute);
|
|
666
|
+
if (!existing2) {
|
|
667
|
+
const promise = notFoundRoute.load();
|
|
668
|
+
prefetchedRoutes.set(notFoundRoute, promise);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
const existing = prefetchedRoutes.get(matched.route);
|
|
674
|
+
if (!existing) {
|
|
675
|
+
const promise = matched.route.load();
|
|
676
|
+
prefetchedRoutes.set(matched.route, promise);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
function createHoverHandler(routes, notFoundRoute) {
|
|
680
|
+
return function handleHover(ev) {
|
|
681
|
+
try {
|
|
682
|
+
const target = ev.target;
|
|
683
|
+
if (!target) return;
|
|
684
|
+
const anchor = target.closest("a[href]");
|
|
685
|
+
if (!anchor) return;
|
|
686
|
+
const href = anchor.getAttribute("href");
|
|
687
|
+
if (!href) return;
|
|
688
|
+
if (href.startsWith("#")) return;
|
|
689
|
+
const url = new URL(href, window.location.href);
|
|
690
|
+
if (url.origin !== window.location.origin) return;
|
|
691
|
+
if (anchor.target && anchor.target !== "_self") return;
|
|
692
|
+
const nextUrl = url.pathname + url.search;
|
|
693
|
+
const currentUrl = window.location.pathname + window.location.search;
|
|
694
|
+
if (nextUrl === currentUrl) return;
|
|
695
|
+
prefetchRoute(nextUrl, routes, notFoundRoute);
|
|
696
|
+
} catch (error) {
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
}
|
|
514
700
|
function createClickHandler(navigate2) {
|
|
515
701
|
return function handleClick(ev) {
|
|
516
702
|
try {
|
|
@@ -621,17 +807,20 @@ function AppShell({
|
|
|
621
807
|
}
|
|
622
808
|
const handleClick = createClickHandler(handleNavigateInternal);
|
|
623
809
|
const handlePopState = createPopStateHandler(handleNavigateInternal);
|
|
810
|
+
const handleHover = createHoverHandler(routes, notFoundRoute);
|
|
624
811
|
window.addEventListener("click", handleClick, false);
|
|
625
812
|
window.addEventListener("popstate", handlePopState, false);
|
|
813
|
+
window.addEventListener("mouseover", handleHover, false);
|
|
626
814
|
return () => {
|
|
627
815
|
isMounted = false;
|
|
628
816
|
window.removeEventListener("click", handleClick, false);
|
|
629
817
|
window.removeEventListener("popstate", handlePopState, false);
|
|
818
|
+
window.removeEventListener("mouseover", handleHover, false);
|
|
630
819
|
};
|
|
631
|
-
}, []);
|
|
820
|
+
}, [routes, notFoundRoute]);
|
|
632
821
|
(0, import_react2.useEffect)(() => {
|
|
633
822
|
const handleDataRefresh = () => {
|
|
634
|
-
const freshData = window
|
|
823
|
+
const freshData = window[WINDOW_DATA_KEY];
|
|
635
824
|
if (!freshData) return;
|
|
636
825
|
const currentPathname = window.location.pathname;
|
|
637
826
|
const freshPathname = freshData.pathname;
|
|
@@ -658,6 +847,91 @@ function AppShell({
|
|
|
658
847
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouterContext.Provider, { value: { navigate: handleNavigate }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouterView, { state }, routeKey) });
|
|
659
848
|
}
|
|
660
849
|
|
|
850
|
+
// modules/runtime/client/hot-reload.ts
|
|
851
|
+
function setupHotReload() {
|
|
852
|
+
const nodeEnv = process.env.NODE_ENV || "production";
|
|
853
|
+
const isDev = nodeEnv === "development";
|
|
854
|
+
console.log(`[hot-reload] NODE_ENV: ${nodeEnv}, isDev: ${isDev}`);
|
|
855
|
+
if (!isDev) {
|
|
856
|
+
console.log("[hot-reload] Skipping hot reload setup (not in development mode)");
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
console.log("[hot-reload] Setting up hot reload client...");
|
|
860
|
+
let eventSource = null;
|
|
861
|
+
let reloadTimeout = null;
|
|
862
|
+
let reconnectTimeout = null;
|
|
863
|
+
let reconnectAttempts = 0;
|
|
864
|
+
const MAX_RECONNECT_ATTEMPTS = 10;
|
|
865
|
+
const RECONNECT_DELAY = 1e3;
|
|
866
|
+
const RELOAD_DELAY = 100;
|
|
867
|
+
function connect() {
|
|
868
|
+
try {
|
|
869
|
+
if (eventSource) {
|
|
870
|
+
console.log("[hot-reload] Closing existing EventSource connection");
|
|
871
|
+
eventSource.close();
|
|
872
|
+
}
|
|
873
|
+
const endpoint = "/__fw/hot";
|
|
874
|
+
eventSource = new EventSource(endpoint);
|
|
875
|
+
eventSource.addEventListener("ping", (event) => {
|
|
876
|
+
if ("data" in event) {
|
|
877
|
+
console.log("[hot-reload] \u2705 Connected to hot reload server");
|
|
878
|
+
}
|
|
879
|
+
reconnectAttempts = 0;
|
|
880
|
+
});
|
|
881
|
+
eventSource.addEventListener("message", (event) => {
|
|
882
|
+
const data = event.data;
|
|
883
|
+
if (data && typeof data === "string" && data.startsWith("reload:")) {
|
|
884
|
+
const filePath = data.slice(7);
|
|
885
|
+
console.log(`[hot-reload] \u{1F4DD} File changed: ${filePath}, reloading...`);
|
|
886
|
+
if (reloadTimeout) {
|
|
887
|
+
clearTimeout(reloadTimeout);
|
|
888
|
+
}
|
|
889
|
+
reloadTimeout = setTimeout(() => {
|
|
890
|
+
try {
|
|
891
|
+
window.location.reload();
|
|
892
|
+
} catch (error) {
|
|
893
|
+
console.error("[hot-reload] \u274C Error reloading page:", error);
|
|
894
|
+
setTimeout(() => window.location.reload(), 100);
|
|
895
|
+
}
|
|
896
|
+
}, RELOAD_DELAY);
|
|
897
|
+
}
|
|
898
|
+
});
|
|
899
|
+
eventSource.onopen = () => {
|
|
900
|
+
reconnectAttempts = 0;
|
|
901
|
+
};
|
|
902
|
+
eventSource.onerror = (error) => {
|
|
903
|
+
const states = ["CONNECTING", "OPEN", "CLOSED"];
|
|
904
|
+
const state = states[eventSource?.readyState ?? 0] || "UNKNOWN";
|
|
905
|
+
if (eventSource?.readyState === EventSource.CONNECTING) {
|
|
906
|
+
console.log("[hot-reload] \u23F3 Still connecting...");
|
|
907
|
+
return;
|
|
908
|
+
} else if (eventSource?.readyState === EventSource.OPEN) {
|
|
909
|
+
console.warn("[hot-reload] \u26A0\uFE0F Connection error (but connection is open):", error);
|
|
910
|
+
} else {
|
|
911
|
+
console.warn(`[hot-reload] \u274C Connection closed (readyState: ${state})`);
|
|
912
|
+
if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
|
|
913
|
+
reconnectAttempts++;
|
|
914
|
+
const delay = RECONNECT_DELAY * reconnectAttempts;
|
|
915
|
+
if (reconnectTimeout) {
|
|
916
|
+
clearTimeout(reconnectTimeout);
|
|
917
|
+
}
|
|
918
|
+
reconnectTimeout = setTimeout(() => {
|
|
919
|
+
console.log(`[hot-reload] \u{1F504} Reconnecting... (attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})`);
|
|
920
|
+
connect();
|
|
921
|
+
}, delay);
|
|
922
|
+
} else {
|
|
923
|
+
console.error("[hot-reload] \u274C Max reconnect attempts reached. Please refresh the page manually.");
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
} catch (error) {
|
|
928
|
+
console.error("[hot-reload] \u274C Failed to create EventSource:", error);
|
|
929
|
+
console.error("[hot-reload] EventSource may not be supported in this browser.");
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
connect();
|
|
933
|
+
}
|
|
934
|
+
|
|
661
935
|
// modules/runtime/client/bootstrap.tsx
|
|
662
936
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
663
937
|
async function loadInitialRoute(initialUrl, initialData, routes, notFoundRoute, errorRoute) {
|
|
@@ -699,101 +973,91 @@ async function loadInitialRoute(initialUrl, initialData, routes, notFoundRoute,
|
|
|
699
973
|
props: initialData?.props ?? {}
|
|
700
974
|
};
|
|
701
975
|
}
|
|
702
|
-
function
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
976
|
+
function initializeRouterData(initialUrl, initialData) {
|
|
977
|
+
let routerData = getRouterData();
|
|
978
|
+
if (!routerData) {
|
|
979
|
+
const url = new URL(initialUrl, window.location.origin);
|
|
980
|
+
routerData = {
|
|
981
|
+
pathname: url.pathname,
|
|
982
|
+
params: initialData?.params || {},
|
|
983
|
+
searchParams: Object.fromEntries(url.searchParams.entries())
|
|
984
|
+
};
|
|
985
|
+
setRouterData(routerData);
|
|
707
986
|
}
|
|
987
|
+
}
|
|
988
|
+
async function hydrateInitialRoute(container, initialUrl, initialData, routes, notFoundRoute, errorRoute) {
|
|
708
989
|
try {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
console.log("[hot-reload] Reloading page...");
|
|
722
|
-
window.location.reload();
|
|
723
|
-
}, 500);
|
|
724
|
-
}
|
|
725
|
-
});
|
|
726
|
-
eventSource.addEventListener("ping", () => {
|
|
727
|
-
console.log("[hot-reload] \u2713 Connected to hot reload server");
|
|
728
|
-
});
|
|
729
|
-
eventSource.onopen = () => {
|
|
730
|
-
console.log("[hot-reload] \u2713 SSE connection opened");
|
|
731
|
-
};
|
|
732
|
-
eventSource.onerror = (error) => {
|
|
733
|
-
const states = ["CONNECTING", "OPEN", "CLOSED"];
|
|
734
|
-
const state = states[eventSource.readyState] || "UNKNOWN";
|
|
735
|
-
if (eventSource.readyState === EventSource.CONNECTING) {
|
|
736
|
-
console.log("[hot-reload] Connecting...");
|
|
737
|
-
} else if (eventSource.readyState === EventSource.OPEN) {
|
|
738
|
-
console.warn("[hot-reload] Connection error (but connection is open):", error);
|
|
739
|
-
} else {
|
|
740
|
-
console.log("[hot-reload] Connection closed (readyState:", state, ")");
|
|
990
|
+
const initialState = await loadInitialRoute(
|
|
991
|
+
initialUrl,
|
|
992
|
+
initialData,
|
|
993
|
+
routes,
|
|
994
|
+
notFoundRoute,
|
|
995
|
+
errorRoute
|
|
996
|
+
);
|
|
997
|
+
if (initialData?.metadata) {
|
|
998
|
+
try {
|
|
999
|
+
applyMetadata(initialData.metadata);
|
|
1000
|
+
} catch (metadataError) {
|
|
1001
|
+
console.warn("[client] Error applying metadata:", metadataError);
|
|
741
1002
|
}
|
|
742
|
-
}
|
|
1003
|
+
}
|
|
1004
|
+
(0, import_client.hydrateRoot)(
|
|
1005
|
+
container,
|
|
1006
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1007
|
+
AppShell,
|
|
1008
|
+
{
|
|
1009
|
+
initialState,
|
|
1010
|
+
routes,
|
|
1011
|
+
notFoundRoute,
|
|
1012
|
+
errorRoute
|
|
1013
|
+
}
|
|
1014
|
+
)
|
|
1015
|
+
);
|
|
743
1016
|
} catch (error) {
|
|
744
|
-
console.
|
|
1017
|
+
console.error(
|
|
1018
|
+
"[client] Error loading initial route components for",
|
|
1019
|
+
initialUrl,
|
|
1020
|
+
error
|
|
1021
|
+
);
|
|
1022
|
+
throw error;
|
|
745
1023
|
}
|
|
746
1024
|
}
|
|
747
1025
|
function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
748
|
-
console.log("[client] Bootstrap starting, setting up hot reload...");
|
|
749
1026
|
setupHotReload();
|
|
750
|
-
(async
|
|
751
|
-
const container = document.getElementById(APP_CONTAINER_ID);
|
|
752
|
-
const initialData = getWindowData();
|
|
753
|
-
if (!container) {
|
|
754
|
-
console.error(`Container #${APP_CONTAINER_ID} not found for hydration`);
|
|
755
|
-
return;
|
|
756
|
-
}
|
|
757
|
-
const initialUrl = window.location.pathname + window.location.search;
|
|
758
|
-
let routerData = getRouterData();
|
|
759
|
-
if (!routerData) {
|
|
760
|
-
const url = new URL(initialUrl, window.location.origin);
|
|
761
|
-
routerData = {
|
|
762
|
-
pathname: url.pathname,
|
|
763
|
-
params: initialData?.params || {},
|
|
764
|
-
searchParams: Object.fromEntries(url.searchParams.entries())
|
|
765
|
-
};
|
|
766
|
-
setRouterData(routerData);
|
|
767
|
-
}
|
|
1027
|
+
(async () => {
|
|
768
1028
|
try {
|
|
769
|
-
const
|
|
1029
|
+
const container = document.getElementById(APP_CONTAINER_ID);
|
|
1030
|
+
if (!container) {
|
|
1031
|
+
console.error(`
|
|
1032
|
+
\u274C [client] Hydration failed: Container #${APP_CONTAINER_ID} not found`);
|
|
1033
|
+
console.error("\u{1F4A1} This usually means:");
|
|
1034
|
+
console.error(" \u2022 The HTML structure doesn't match what React expects");
|
|
1035
|
+
console.error(" \u2022 The container was removed before hydration");
|
|
1036
|
+
console.error(" \u2022 There's a mismatch between SSR and client HTML\n");
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
const initialData = getWindowData();
|
|
1040
|
+
const initialUrl = window.location.pathname + window.location.search;
|
|
1041
|
+
initializeRouterData(initialUrl, initialData);
|
|
1042
|
+
await hydrateInitialRoute(
|
|
1043
|
+
container,
|
|
770
1044
|
initialUrl,
|
|
771
1045
|
initialData,
|
|
772
1046
|
routes,
|
|
773
1047
|
notFoundRoute,
|
|
774
1048
|
errorRoute
|
|
775
1049
|
);
|
|
776
|
-
if (initialData?.metadata) {
|
|
777
|
-
applyMetadata(initialData.metadata);
|
|
778
|
-
}
|
|
779
|
-
(0, import_client.hydrateRoot)(
|
|
780
|
-
container,
|
|
781
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
782
|
-
AppShell,
|
|
783
|
-
{
|
|
784
|
-
initialState,
|
|
785
|
-
routes,
|
|
786
|
-
notFoundRoute,
|
|
787
|
-
errorRoute
|
|
788
|
-
}
|
|
789
|
-
)
|
|
790
|
-
);
|
|
791
1050
|
} catch (error) {
|
|
792
|
-
console.error(
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
error
|
|
796
|
-
|
|
1051
|
+
console.error("\n\u274C [client] Fatal error during bootstrap:");
|
|
1052
|
+
console.error(error);
|
|
1053
|
+
if (error instanceof Error) {
|
|
1054
|
+
console.error("\nError details:");
|
|
1055
|
+
console.error(` Message: ${error.message}`);
|
|
1056
|
+
if (error.stack) {
|
|
1057
|
+
console.error(` Stack: ${error.stack}`);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
console.error("\n\u{1F4A1} Attempting page reload to recover...\n");
|
|
797
1061
|
window.location.reload();
|
|
798
1062
|
}
|
|
799
1063
|
})();
|