@lolyjs/core 0.1.0-alpha.9 → 0.2.0-alpha.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 +467 -325
- package/dist/bootstrap-BiCQmSkx.d.mts +50 -0
- package/dist/bootstrap-BiCQmSkx.d.ts +50 -0
- package/dist/cli.cjs +98 -20
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +98 -20
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +169 -158
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +2 -35
- package/dist/index.d.ts +2 -35
- package/dist/index.js +169 -158
- package/dist/index.js.map +1 -1
- package/dist/react/hooks.cjs +5 -5
- package/dist/react/hooks.cjs.map +1 -1
- package/dist/react/hooks.d.mts +13 -3
- package/dist/react/hooks.d.ts +13 -3
- package/dist/react/hooks.js +5 -5
- package/dist/react/hooks.js.map +1 -1
- package/dist/react/sockets.cjs +5 -1
- package/dist/react/sockets.cjs.map +1 -1
- package/dist/react/sockets.js +5 -1
- package/dist/react/sockets.js.map +1 -1
- package/dist/runtime.cjs +91 -160
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.mts +3 -45
- package/dist/runtime.d.ts +3 -45
- package/dist/runtime.js +87 -160
- package/dist/runtime.js.map +1 -1
- package/package.json +2 -4
package/dist/runtime.js
CHANGED
|
@@ -7,8 +7,7 @@ var APP_CONTAINER_ID = "__app";
|
|
|
7
7
|
|
|
8
8
|
// modules/runtime/client/window-data.ts
|
|
9
9
|
function getWindowData() {
|
|
10
|
-
|
|
11
|
-
return (_a = window[WINDOW_DATA_KEY]) != null ? _a : null;
|
|
10
|
+
return window[WINDOW_DATA_KEY] ?? null;
|
|
12
11
|
}
|
|
13
12
|
function setWindowData(data) {
|
|
14
13
|
window[WINDOW_DATA_KEY] = data;
|
|
@@ -21,8 +20,7 @@ function setWindowData(data) {
|
|
|
21
20
|
}
|
|
22
21
|
}
|
|
23
22
|
function getCurrentTheme() {
|
|
24
|
-
|
|
25
|
-
return (_b = (_a = getWindowData()) == null ? void 0 : _a.theme) != null ? _b : null;
|
|
23
|
+
return getWindowData()?.theme ?? null;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
// modules/runtime/client/route-matcher.ts
|
|
@@ -90,11 +88,6 @@ import { useEffect, useState, useRef } from "react";
|
|
|
90
88
|
// modules/runtime/client/RouterView.tsx
|
|
91
89
|
import { jsx } from "react/jsx-runtime";
|
|
92
90
|
function RouterView({ state }) {
|
|
93
|
-
console.log("[loly:RouterView] Rendering", {
|
|
94
|
-
url: state.url,
|
|
95
|
-
hasRoute: !!state.route,
|
|
96
|
-
hasComponents: !!state.components
|
|
97
|
-
});
|
|
98
91
|
if (!state.route) {
|
|
99
92
|
if (state.components === null) {
|
|
100
93
|
return null;
|
|
@@ -106,11 +99,6 @@ function RouterView({ state }) {
|
|
|
106
99
|
}
|
|
107
100
|
const { Page, layouts } = state.components;
|
|
108
101
|
const { params, props } = state;
|
|
109
|
-
console.log("[loly:RouterView] Creating page element", {
|
|
110
|
-
hasPage: !!Page,
|
|
111
|
-
layoutsCount: layouts.length,
|
|
112
|
-
paramsKeys: Object.keys(params)
|
|
113
|
-
});
|
|
114
102
|
let element = /* @__PURE__ */ jsx(Page, { params, ...props });
|
|
115
103
|
const layoutChain = layouts.slice().reverse();
|
|
116
104
|
for (const Layout of layoutChain) {
|
|
@@ -179,7 +167,7 @@ function evictOldest() {
|
|
|
179
167
|
}
|
|
180
168
|
function setCacheEntry(key, entry) {
|
|
181
169
|
const existingEntry = dataCache.get(key);
|
|
182
|
-
const wasFulfilled =
|
|
170
|
+
const wasFulfilled = existingEntry?.status === "fulfilled";
|
|
183
171
|
dataCache.set(key, entry);
|
|
184
172
|
if (entry.status === "fulfilled") {
|
|
185
173
|
if (!wasFulfilled) {
|
|
@@ -233,7 +221,7 @@ async function fetchRouteDataOnce(url) {
|
|
|
233
221
|
}
|
|
234
222
|
async function getRouteData(url, options) {
|
|
235
223
|
const key = buildDataUrl(url);
|
|
236
|
-
if (options
|
|
224
|
+
if (options?.revalidate) {
|
|
237
225
|
deleteCacheEntry(key);
|
|
238
226
|
}
|
|
239
227
|
const entry = dataCache.get(key);
|
|
@@ -260,7 +248,6 @@ async function getRouteData(url, options) {
|
|
|
260
248
|
|
|
261
249
|
// modules/runtime/client/navigation.ts
|
|
262
250
|
async function handleErrorRoute(nextUrl, json, errorRoute, setState) {
|
|
263
|
-
var _a;
|
|
264
251
|
try {
|
|
265
252
|
const components = await errorRoute.load();
|
|
266
253
|
let theme = "light";
|
|
@@ -287,7 +274,7 @@ async function handleErrorRoute(nextUrl, json, errorRoute, setState) {
|
|
|
287
274
|
pathname: nextUrl,
|
|
288
275
|
params: json.params || {},
|
|
289
276
|
props: errorProps,
|
|
290
|
-
metadata:
|
|
277
|
+
metadata: json.metadata ?? null,
|
|
291
278
|
theme,
|
|
292
279
|
notFound: false,
|
|
293
280
|
error: true
|
|
@@ -311,7 +298,6 @@ async function handleErrorRoute(nextUrl, json, errorRoute, setState) {
|
|
|
311
298
|
}
|
|
312
299
|
}
|
|
313
300
|
async function handleNotFoundRoute(nextUrl, json, notFoundRoute, setState) {
|
|
314
|
-
var _a, _b;
|
|
315
301
|
let theme = "light";
|
|
316
302
|
if (typeof document !== "undefined") {
|
|
317
303
|
const cookieMatch = document.cookie.match(/theme=([^;]+)/);
|
|
@@ -327,14 +313,14 @@ async function handleNotFoundRoute(nextUrl, json, notFoundRoute, setState) {
|
|
|
327
313
|
theme = json.theme;
|
|
328
314
|
}
|
|
329
315
|
const notFoundProps = {
|
|
330
|
-
...
|
|
316
|
+
...json.props ?? {},
|
|
331
317
|
theme
|
|
332
318
|
};
|
|
333
319
|
const windowData = {
|
|
334
320
|
pathname: nextUrl,
|
|
335
321
|
params: {},
|
|
336
322
|
props: notFoundProps,
|
|
337
|
-
metadata:
|
|
323
|
+
metadata: json.metadata ?? null,
|
|
338
324
|
theme,
|
|
339
325
|
notFound: true,
|
|
340
326
|
error: false
|
|
@@ -360,8 +346,7 @@ async function handleNotFoundRoute(nextUrl, json, notFoundRoute, setState) {
|
|
|
360
346
|
}
|
|
361
347
|
}
|
|
362
348
|
async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
363
|
-
|
|
364
|
-
applyMetadata((_a = json.metadata) != null ? _a : null);
|
|
349
|
+
applyMetadata(json.metadata ?? null);
|
|
365
350
|
let theme = "light";
|
|
366
351
|
if (typeof document !== "undefined") {
|
|
367
352
|
const cookieMatch = document.cookie.match(/theme=([^;]+)/);
|
|
@@ -379,7 +364,7 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
379
364
|
theme = json.theme;
|
|
380
365
|
}
|
|
381
366
|
const newProps = {
|
|
382
|
-
...
|
|
367
|
+
...json.props ?? {},
|
|
383
368
|
theme
|
|
384
369
|
// Always include theme
|
|
385
370
|
};
|
|
@@ -392,7 +377,7 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
392
377
|
pathname: nextUrl,
|
|
393
378
|
params: matched.params,
|
|
394
379
|
props: newProps,
|
|
395
|
-
metadata:
|
|
380
|
+
metadata: json.metadata ?? null,
|
|
396
381
|
theme,
|
|
397
382
|
notFound: false,
|
|
398
383
|
error: false
|
|
@@ -416,10 +401,9 @@ async function navigate(nextUrl, handlers, options) {
|
|
|
416
401
|
const { setState, routes, notFoundRoute, errorRoute } = handlers;
|
|
417
402
|
try {
|
|
418
403
|
const { ok, json } = await getRouteData(nextUrl, {
|
|
419
|
-
revalidate: options
|
|
404
|
+
revalidate: options?.revalidate
|
|
420
405
|
});
|
|
421
406
|
if (json && json.error) {
|
|
422
|
-
console.log("[client] Error detected in response:", json);
|
|
423
407
|
if (errorRoute) {
|
|
424
408
|
const handled = await handleErrorRoute(
|
|
425
409
|
nextUrl,
|
|
@@ -461,50 +445,23 @@ async function navigate(nextUrl, handlers, options) {
|
|
|
461
445
|
}
|
|
462
446
|
function createClickHandler(navigate2) {
|
|
463
447
|
return function handleClick(ev) {
|
|
464
|
-
const target = ev.target;
|
|
465
|
-
const tagName = (target == null ? void 0 : target.tagName.toLowerCase()) || "unknown";
|
|
466
|
-
console.log("[loly:click] Click event received", {
|
|
467
|
-
type: ev.type,
|
|
468
|
-
tagName,
|
|
469
|
-
target: target == null ? void 0 : target.tagName,
|
|
470
|
-
defaultPrevented: ev.defaultPrevented,
|
|
471
|
-
button: ev.button,
|
|
472
|
-
clientX: ev.clientX,
|
|
473
|
-
clientY: ev.clientY
|
|
474
|
-
});
|
|
475
448
|
try {
|
|
476
|
-
if (ev.defaultPrevented)
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
console.log("[loly:click] Not a click event, skipping", { type: ev.type });
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
if (ev.button !== 0) {
|
|
485
|
-
console.log("[loly:click] Not left button, skipping", { button: ev.button });
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
if (ev.metaKey || ev.ctrlKey || ev.shiftKey || ev.altKey) {
|
|
489
|
-
console.log("[loly:click] Modifier keys pressed, skipping");
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
449
|
+
if (ev.defaultPrevented) return;
|
|
450
|
+
if (ev.type !== "click") return;
|
|
451
|
+
if (ev.button !== 0) return;
|
|
452
|
+
if (ev.metaKey || ev.ctrlKey || ev.shiftKey || ev.altKey) return;
|
|
453
|
+
const target = ev.target;
|
|
492
454
|
if (ev.clientX === 0 && ev.clientY === 0 && ev.detail === 0) {
|
|
493
455
|
if (target) {
|
|
494
|
-
const
|
|
495
|
-
if (
|
|
496
|
-
console.log("[loly:click] Synthetic event on interactive element, skipping", { tagName: tagName3 });
|
|
456
|
+
const tagName2 = target.tagName.toLowerCase();
|
|
457
|
+
if (tagName2 === "input" || tagName2 === "textarea" || tagName2 === "button" || tagName2 === "select") {
|
|
497
458
|
return;
|
|
498
459
|
}
|
|
499
460
|
}
|
|
500
461
|
}
|
|
501
|
-
if (!target)
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
}
|
|
505
|
-
const tagName2 = target.tagName.toLowerCase();
|
|
506
|
-
if (tagName2 === "input" || tagName2 === "textarea" || tagName2 === "button" || tagName2 === "select" || target.isContentEditable || target.getAttribute("contenteditable") === "true") {
|
|
507
|
-
console.log("[loly:click] Target is interactive element, skipping", { tagName: tagName2 });
|
|
462
|
+
if (!target) return;
|
|
463
|
+
const tagName = target.tagName.toLowerCase();
|
|
464
|
+
if (tagName === "input" || tagName === "textarea" || tagName === "button" || tagName === "select" || target.isContentEditable || target.getAttribute("contenteditable") === "true") {
|
|
508
465
|
return;
|
|
509
466
|
}
|
|
510
467
|
const interactiveParent = target.closest("input, textarea, button, select, [contenteditable], label");
|
|
@@ -512,60 +469,29 @@ function createClickHandler(navigate2) {
|
|
|
512
469
|
if (interactiveParent.tagName.toLowerCase() === "label") {
|
|
513
470
|
const label = interactiveParent;
|
|
514
471
|
if (label.control) {
|
|
515
|
-
console.log("[loly:click] Inside label with control, skipping");
|
|
516
472
|
return;
|
|
517
473
|
}
|
|
518
474
|
} else {
|
|
519
|
-
console.log("[loly:click] Inside interactive parent, skipping", {
|
|
520
|
-
parentTag: interactiveParent.tagName.toLowerCase()
|
|
521
|
-
});
|
|
522
475
|
return;
|
|
523
476
|
}
|
|
524
477
|
}
|
|
525
478
|
const anchor = target.closest("a[href]");
|
|
526
|
-
if (!anchor)
|
|
527
|
-
console.log("[loly:click] No anchor found, skipping");
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
console.log("[loly:click] Anchor found, processing navigation", {
|
|
531
|
-
href: anchor.getAttribute("href")
|
|
532
|
-
});
|
|
479
|
+
if (!anchor) return;
|
|
533
480
|
const href = anchor.getAttribute("href");
|
|
534
|
-
if (!href)
|
|
535
|
-
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
if (href.startsWith("#")) {
|
|
539
|
-
console.log("[loly:click] Hash link, skipping");
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
481
|
+
if (!href) return;
|
|
482
|
+
if (href.startsWith("#")) return;
|
|
542
483
|
const url = new URL(href, window.location.href);
|
|
543
|
-
if (url.origin !== window.location.origin)
|
|
544
|
-
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
|
-
if (anchor.target && anchor.target !== "_self") {
|
|
548
|
-
console.log("[loly:click] Link has target, skipping", { target: anchor.target });
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
484
|
+
if (url.origin !== window.location.origin) return;
|
|
485
|
+
if (anchor.target && anchor.target !== "_self") return;
|
|
551
486
|
ev.preventDefault();
|
|
552
|
-
console.log("[loly:click] Prevented default, navigating");
|
|
553
487
|
const nextUrl = url.pathname + url.search;
|
|
554
488
|
const currentUrl = window.location.pathname + window.location.search;
|
|
555
|
-
if (nextUrl === currentUrl)
|
|
556
|
-
console.log("[loly:click] Same URL, skipping", { nextUrl });
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
489
|
+
if (nextUrl === currentUrl) return;
|
|
559
490
|
const shouldRevalidate = anchor.hasAttribute("data-revalidate") && anchor.getAttribute("data-revalidate") !== "false";
|
|
560
|
-
console.log("[loly:click] Pushing state and navigating", {
|
|
561
|
-
nextUrl,
|
|
562
|
-
currentUrl,
|
|
563
|
-
shouldRevalidate
|
|
564
|
-
});
|
|
565
491
|
window.history.pushState({}, "", nextUrl);
|
|
566
492
|
navigate2(nextUrl, shouldRevalidate ? { revalidate: true } : void 0);
|
|
567
493
|
} catch (error) {
|
|
568
|
-
console.error("[
|
|
494
|
+
console.error("[navigation] Error in click handler:", error);
|
|
569
495
|
}
|
|
570
496
|
};
|
|
571
497
|
}
|
|
@@ -584,10 +510,6 @@ function AppShell({
|
|
|
584
510
|
notFoundRoute,
|
|
585
511
|
errorRoute
|
|
586
512
|
}) {
|
|
587
|
-
console.log("[loly:AppShell] Component rendering", {
|
|
588
|
-
url: initialState.url,
|
|
589
|
-
hasRoute: !!initialState.route
|
|
590
|
-
});
|
|
591
513
|
const [state, setState] = useState(initialState);
|
|
592
514
|
const handlersRef = useRef({
|
|
593
515
|
setState,
|
|
@@ -596,11 +518,6 @@ function AppShell({
|
|
|
596
518
|
errorRoute
|
|
597
519
|
});
|
|
598
520
|
useEffect(() => {
|
|
599
|
-
console.log("[loly:AppShell] Updating handlersRef", {
|
|
600
|
-
routesCount: routes.length,
|
|
601
|
-
hasNotFound: !!notFoundRoute,
|
|
602
|
-
hasError: !!errorRoute
|
|
603
|
-
});
|
|
604
521
|
handlersRef.current = {
|
|
605
522
|
setState,
|
|
606
523
|
routes,
|
|
@@ -609,34 +526,16 @@ function AppShell({
|
|
|
609
526
|
};
|
|
610
527
|
}, [routes, notFoundRoute, errorRoute]);
|
|
611
528
|
useEffect(() => {
|
|
612
|
-
const effectId = Math.random().toString(36).substring(7);
|
|
613
|
-
console.log("[loly:AppShell] Setting up event listeners", { effectId });
|
|
614
529
|
let isMounted = true;
|
|
615
|
-
let listenerCount = 0;
|
|
616
530
|
async function handleNavigate(nextUrl, options) {
|
|
617
|
-
if (!isMounted)
|
|
618
|
-
console.warn("[loly:AppShell] navigate called but component is unmounted");
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
console.log("[loly:AppShell] Navigating to", nextUrl, options);
|
|
531
|
+
if (!isMounted) return;
|
|
622
532
|
await navigate(nextUrl, handlersRef.current, options);
|
|
623
533
|
}
|
|
624
534
|
const handleClick = createClickHandler(handleNavigate);
|
|
625
535
|
const handlePopState = createPopStateHandler(handleNavigate);
|
|
626
536
|
window.addEventListener("click", handleClick, false);
|
|
627
537
|
window.addEventListener("popstate", handlePopState, false);
|
|
628
|
-
listenerCount = 2;
|
|
629
|
-
console.log("[loly:AppShell] Event listeners added", {
|
|
630
|
-
clickListener: true,
|
|
631
|
-
popStateListener: true,
|
|
632
|
-
totalListeners: listenerCount
|
|
633
|
-
});
|
|
634
538
|
return () => {
|
|
635
|
-
console.log("[loly:AppShell] Cleaning up event listeners", {
|
|
636
|
-
effectId,
|
|
637
|
-
wasMounted: isMounted,
|
|
638
|
-
listenersToRemove: listenerCount
|
|
639
|
-
});
|
|
640
539
|
isMounted = false;
|
|
641
540
|
window.removeEventListener("click", handleClick, false);
|
|
642
541
|
window.removeEventListener("popstate", handlePopState, false);
|
|
@@ -651,17 +550,15 @@ function AppShell({
|
|
|
651
550
|
|
|
652
551
|
// modules/runtime/client/bootstrap.tsx
|
|
653
552
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
654
|
-
var __loly_hydrated = false;
|
|
655
553
|
async function loadInitialRoute(initialUrl, initialData, routes, notFoundRoute, errorRoute) {
|
|
656
|
-
|
|
657
|
-
const
|
|
658
|
-
const isInitialError = (initialData == null ? void 0 : initialData.error) === true;
|
|
554
|
+
const isInitialNotFound = initialData?.notFound === true;
|
|
555
|
+
const isInitialError = initialData?.error === true;
|
|
659
556
|
let initialRoute = null;
|
|
660
557
|
let initialParams = {};
|
|
661
558
|
let initialComponents = null;
|
|
662
559
|
if (isInitialError && errorRoute) {
|
|
663
560
|
initialRoute = errorRoute;
|
|
664
|
-
initialParams =
|
|
561
|
+
initialParams = initialData?.params ?? {};
|
|
665
562
|
initialComponents = await errorRoute.load();
|
|
666
563
|
} else if (isInitialNotFound && notFoundRoute) {
|
|
667
564
|
initialRoute = notFoundRoute;
|
|
@@ -679,7 +576,7 @@ async function loadInitialRoute(initialUrl, initialData, routes, notFoundRoute,
|
|
|
679
576
|
initialComponents = await notFoundRoute.load();
|
|
680
577
|
} else {
|
|
681
578
|
console.warn(
|
|
682
|
-
`[client] No route match found for ${initialUrl}.
|
|
579
|
+
`[client] No route match found for ${initialUrl}. Available routes:`,
|
|
683
580
|
routes.map((r) => r.pattern)
|
|
684
581
|
);
|
|
685
582
|
}
|
|
@@ -689,32 +586,65 @@ async function loadInitialRoute(initialUrl, initialData, routes, notFoundRoute,
|
|
|
689
586
|
route: initialRoute,
|
|
690
587
|
params: initialParams,
|
|
691
588
|
components: initialComponents,
|
|
692
|
-
props:
|
|
589
|
+
props: initialData?.props ?? {}
|
|
693
590
|
};
|
|
694
591
|
}
|
|
695
|
-
function
|
|
696
|
-
|
|
697
|
-
|
|
592
|
+
function setupHotReload() {
|
|
593
|
+
const nodeEnv = typeof process !== "undefined" && process?.env?.NODE_ENV || "production";
|
|
594
|
+
const isDev = nodeEnv !== "production";
|
|
595
|
+
if (!isDev) {
|
|
698
596
|
return;
|
|
699
597
|
}
|
|
700
|
-
|
|
701
|
-
|
|
598
|
+
try {
|
|
599
|
+
console.log("[hot-reload] Attempting to connect to /__fw/hot...");
|
|
600
|
+
const eventSource = new EventSource("/__fw/hot");
|
|
601
|
+
let reloadTimeout = null;
|
|
602
|
+
eventSource.addEventListener("message", (event) => {
|
|
603
|
+
const data = event.data;
|
|
604
|
+
if (data && data.startsWith("reload:")) {
|
|
605
|
+
const filePath = data.slice(7);
|
|
606
|
+
console.log(`[hot-reload] File changed: ${filePath}`);
|
|
607
|
+
if (reloadTimeout) {
|
|
608
|
+
clearTimeout(reloadTimeout);
|
|
609
|
+
}
|
|
610
|
+
reloadTimeout = setTimeout(() => {
|
|
611
|
+
console.log("[hot-reload] Reloading page...");
|
|
612
|
+
window.location.reload();
|
|
613
|
+
}, 500);
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
eventSource.addEventListener("ping", () => {
|
|
617
|
+
console.log("[hot-reload] \u2713 Connected to hot reload server");
|
|
618
|
+
});
|
|
619
|
+
eventSource.onopen = () => {
|
|
620
|
+
console.log("[hot-reload] \u2713 SSE connection opened");
|
|
621
|
+
};
|
|
622
|
+
eventSource.onerror = (error) => {
|
|
623
|
+
const states = ["CONNECTING", "OPEN", "CLOSED"];
|
|
624
|
+
const state = states[eventSource.readyState] || "UNKNOWN";
|
|
625
|
+
if (eventSource.readyState === EventSource.CONNECTING) {
|
|
626
|
+
console.log("[hot-reload] Connecting...");
|
|
627
|
+
} else if (eventSource.readyState === EventSource.OPEN) {
|
|
628
|
+
console.warn("[hot-reload] Connection error (but connection is open):", error);
|
|
629
|
+
} else {
|
|
630
|
+
console.log("[hot-reload] Connection closed (readyState:", state, ")");
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
} catch (error) {
|
|
634
|
+
console.log("[hot-reload] EventSource not supported or error:", error);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
638
|
+
console.log("[client] Bootstrap starting, setting up hot reload...");
|
|
639
|
+
setupHotReload();
|
|
702
640
|
(async function bootstrap() {
|
|
703
641
|
const container = document.getElementById(APP_CONTAINER_ID);
|
|
704
642
|
const initialData = getWindowData();
|
|
705
|
-
console.log("[loly:runtime] bootstrap starting", {
|
|
706
|
-
hasContainer: !!container,
|
|
707
|
-
hasInitialData: !!initialData,
|
|
708
|
-
containerId: APP_CONTAINER_ID
|
|
709
|
-
});
|
|
710
643
|
if (!container) {
|
|
711
|
-
console.error(
|
|
712
|
-
`[loly:runtime] Container #${APP_CONTAINER_ID} not found.`
|
|
713
|
-
);
|
|
644
|
+
console.error(`Container #${APP_CONTAINER_ID} not found for hydration`);
|
|
714
645
|
return;
|
|
715
646
|
}
|
|
716
647
|
const initialUrl = window.location.pathname + window.location.search;
|
|
717
|
-
console.log("[loly:runtime] Loading initial route", { initialUrl });
|
|
718
648
|
try {
|
|
719
649
|
const initialState = await loadInitialRoute(
|
|
720
650
|
initialUrl,
|
|
@@ -723,15 +653,9 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
723
653
|
notFoundRoute,
|
|
724
654
|
errorRoute
|
|
725
655
|
);
|
|
726
|
-
|
|
727
|
-
url: initialState.url,
|
|
728
|
-
hasRoute: !!initialState.route,
|
|
729
|
-
hasComponents: !!initialState.components
|
|
730
|
-
});
|
|
731
|
-
if (initialData == null ? void 0 : initialData.metadata) {
|
|
656
|
+
if (initialData?.metadata) {
|
|
732
657
|
applyMetadata(initialData.metadata);
|
|
733
658
|
}
|
|
734
|
-
console.log("[loly:runtime] Hydrating React app");
|
|
735
659
|
hydrateRoot(
|
|
736
660
|
container,
|
|
737
661
|
/* @__PURE__ */ jsx3(
|
|
@@ -744,9 +668,12 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
744
668
|
}
|
|
745
669
|
)
|
|
746
670
|
);
|
|
747
|
-
console.log("[loly:runtime] Hydrated successfully");
|
|
748
671
|
} catch (error) {
|
|
749
|
-
console.error(
|
|
672
|
+
console.error(
|
|
673
|
+
"[client] Error loading initial route components for",
|
|
674
|
+
initialUrl,
|
|
675
|
+
error
|
|
676
|
+
);
|
|
750
677
|
window.location.reload();
|
|
751
678
|
}
|
|
752
679
|
})();
|