@lolyjs/core 0.3.0-alpha.6 → 0.4.0-alpha.0
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 +88 -0
- package/dist/{bootstrap-BfGTMUkj.d.mts → bootstrap-B6W6XoI5.d.mts} +6 -0
- package/dist/{bootstrap-BfGTMUkj.d.ts → bootstrap-B6W6XoI5.d.ts} +6 -0
- package/dist/cli.cjs +2969 -977
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +2936 -949
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +3159 -937
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +3136 -920
- package/dist/index.mjs.map +1 -1
- package/dist/react/cache.cjs.map +1 -1
- package/dist/react/cache.mjs.map +1 -1
- package/dist/react/components.cjs +16 -0
- package/dist/react/components.cjs.map +1 -1
- package/dist/react/components.d.mts +40 -2
- package/dist/react/components.d.ts +40 -2
- package/dist/react/components.mjs +15 -0
- package/dist/react/components.mjs.map +1 -1
- package/dist/react/hooks.cjs +24 -0
- package/dist/react/hooks.cjs.map +1 -1
- package/dist/react/hooks.d.mts +49 -1
- package/dist/react/hooks.d.ts +49 -1
- package/dist/react/hooks.mjs +22 -0
- package/dist/react/hooks.mjs.map +1 -1
- package/dist/react/themes.cjs +0 -169
- package/dist/react/themes.cjs.map +1 -1
- package/dist/react/themes.d.mts +18 -11
- package/dist/react/themes.d.ts +18 -11
- package/dist/react/themes.mjs +0 -159
- package/dist/react/themes.mjs.map +1 -1
- package/dist/runtime.cjs +268 -24
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.mjs +255 -15
- package/dist/runtime.mjs.map +1 -1
- package/package.json +2 -2
package/dist/runtime.cjs
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
8
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -15,8 +20,104 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
20
|
}
|
|
16
21
|
return to;
|
|
17
22
|
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
18
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
32
|
|
|
33
|
+
// modules/runtime/client/mount-client-islands.ts
|
|
34
|
+
var mount_client_islands_exports = {};
|
|
35
|
+
__export(mount_client_islands_exports, {
|
|
36
|
+
mountClientIslands: () => mountClientIslands
|
|
37
|
+
});
|
|
38
|
+
function getClientComponentLoaders() {
|
|
39
|
+
if (typeof window === "undefined") return null;
|
|
40
|
+
return window.__LOLY_CLIENT_COMPONENT_LOADERS__ || null;
|
|
41
|
+
}
|
|
42
|
+
function normalizeClientFilePath(filePath) {
|
|
43
|
+
return filePath.replace(/\\/g, "/");
|
|
44
|
+
}
|
|
45
|
+
async function loadClientComponentModule(filePath) {
|
|
46
|
+
const loaders = getClientComponentLoaders();
|
|
47
|
+
if (!loaders) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`[client] Missing __LOLY_CLIENT_COMPONENT_LOADERS__. Expected bootstrap to register loaders from .loly/client-components-loaders.ts`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
const normalized = normalizeClientFilePath(filePath);
|
|
53
|
+
const loader = loaders[normalized];
|
|
54
|
+
if (!loader) {
|
|
55
|
+
const known = Object.keys(loaders);
|
|
56
|
+
throw new Error(
|
|
57
|
+
`[client] No loader found for "${normalized}". Known loaders: ${known.slice(0, 10).join(", ")}${known.length > 10 ? "..." : ""}`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return loader();
|
|
61
|
+
}
|
|
62
|
+
async function loadClientComponentExport(filePath, exportName = "default") {
|
|
63
|
+
const mod = await loadClientComponentModule(filePath);
|
|
64
|
+
return exportName === "default" ? mod.default : mod[exportName];
|
|
65
|
+
}
|
|
66
|
+
async function mountClientIslands(container) {
|
|
67
|
+
const placeholders = container.querySelectorAll("[data-client-component]");
|
|
68
|
+
if (placeholders.length === 0) return;
|
|
69
|
+
const promises = Array.from(placeholders).map(async (placeholder) => {
|
|
70
|
+
const filePath = placeholder.getAttribute("data-client-file");
|
|
71
|
+
const exportName = placeholder.getAttribute("data-export-name") || "default";
|
|
72
|
+
const propsJson = placeholder.getAttribute("data-client-props");
|
|
73
|
+
if (!filePath) {
|
|
74
|
+
console.warn("[client] Missing filePath for component");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
let props = {};
|
|
78
|
+
if (propsJson) {
|
|
79
|
+
try {
|
|
80
|
+
props = JSON.parse(propsJson);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.warn("[client] Failed to parse props", e);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const Component = await loadClientComponentExport(filePath, exportName);
|
|
87
|
+
if (!Component) throw new Error(`Component export "${exportName}" not found`);
|
|
88
|
+
const placeholderElement = placeholder;
|
|
89
|
+
while (placeholderElement.firstChild) {
|
|
90
|
+
placeholderElement.removeChild(placeholderElement.firstChild);
|
|
91
|
+
}
|
|
92
|
+
const root = (0, import_client.createRoot)(placeholderElement);
|
|
93
|
+
root.render(import_react4.default.createElement(Component, props));
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error("[client] Failed to mount component:", error);
|
|
96
|
+
const placeholderElement = placeholder;
|
|
97
|
+
while (placeholderElement.firstChild) {
|
|
98
|
+
placeholderElement.removeChild(placeholderElement.firstChild);
|
|
99
|
+
}
|
|
100
|
+
const root = (0, import_client.createRoot)(placeholderElement);
|
|
101
|
+
root.render(
|
|
102
|
+
import_react4.default.createElement(
|
|
103
|
+
"div",
|
|
104
|
+
{ style: { padding: "1rem", border: "1px solid red", color: "red" } },
|
|
105
|
+
"Failed to load component"
|
|
106
|
+
)
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
await Promise.all(promises);
|
|
111
|
+
}
|
|
112
|
+
var import_react4, import_client;
|
|
113
|
+
var init_mount_client_islands = __esm({
|
|
114
|
+
"modules/runtime/client/mount-client-islands.ts"() {
|
|
115
|
+
"use strict";
|
|
116
|
+
import_react4 = __toESM(require("react"));
|
|
117
|
+
import_client = require("react-dom/client");
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
20
121
|
// modules/runtime/client/index.tsx
|
|
21
122
|
var client_exports = {};
|
|
22
123
|
__export(client_exports, {
|
|
@@ -25,7 +126,7 @@ __export(client_exports, {
|
|
|
25
126
|
module.exports = __toCommonJS(client_exports);
|
|
26
127
|
|
|
27
128
|
// modules/runtime/client/bootstrap.tsx
|
|
28
|
-
var
|
|
129
|
+
var import_client2 = require("react-dom/client");
|
|
29
130
|
|
|
30
131
|
// modules/runtime/client/constants.ts
|
|
31
132
|
var WINDOW_DATA_KEY = "__FW_DATA__";
|
|
@@ -285,9 +386,10 @@ function applyMetadata(md) {
|
|
|
285
386
|
}
|
|
286
387
|
|
|
287
388
|
// modules/runtime/client/AppShell.tsx
|
|
288
|
-
var
|
|
389
|
+
var import_react3 = require("react");
|
|
289
390
|
|
|
290
391
|
// modules/runtime/client/RouterView.tsx
|
|
392
|
+
var import_react = __toESM(require("react"));
|
|
291
393
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
292
394
|
function RouterView({ state }) {
|
|
293
395
|
if (!state.route) {
|
|
@@ -299,12 +401,23 @@ function RouterView({ state }) {
|
|
|
299
401
|
if (!state.components) {
|
|
300
402
|
return null;
|
|
301
403
|
}
|
|
302
|
-
const {
|
|
404
|
+
const {
|
|
405
|
+
Page,
|
|
406
|
+
layouts,
|
|
407
|
+
isPageClientComponent,
|
|
408
|
+
isLayoutClientComponent,
|
|
409
|
+
clientComponentFilePaths
|
|
410
|
+
} = state.components;
|
|
303
411
|
const { params, props } = state;
|
|
304
|
-
let element =
|
|
412
|
+
let element = isPageClientComponent && clientComponentFilePaths?.page ? null : import_react.default.createElement(Page, { params, ...props });
|
|
305
413
|
const layoutChain = layouts.slice().reverse();
|
|
306
|
-
|
|
307
|
-
|
|
414
|
+
const isLayoutClientComponentReversed = (isLayoutClientComponent || []).slice().reverse();
|
|
415
|
+
const clientComponentLayoutPaths = (clientComponentFilePaths?.layouts || []).slice().reverse();
|
|
416
|
+
for (let i = 0; i < layoutChain.length; i++) {
|
|
417
|
+
const Layout = layoutChain[i];
|
|
418
|
+
const isClient = isLayoutClientComponentReversed[i];
|
|
419
|
+
const layoutPath = clientComponentLayoutPaths[i];
|
|
420
|
+
element = isClient && layoutPath ? element : import_react.default.createElement(Layout, { params, ...props, children: element });
|
|
308
421
|
}
|
|
309
422
|
return element;
|
|
310
423
|
}
|
|
@@ -468,9 +581,46 @@ async function getRouteData(url, options) {
|
|
|
468
581
|
}
|
|
469
582
|
|
|
470
583
|
// modules/runtime/client/navigation.ts
|
|
584
|
+
function detectClientComponents(routePattern, components) {
|
|
585
|
+
let dependenciesManifest = null;
|
|
586
|
+
if (typeof window !== "undefined" && window.__LOLY_ROUTE_DEPENDENCIES__) {
|
|
587
|
+
dependenciesManifest = window.__LOLY_ROUTE_DEPENDENCIES__;
|
|
588
|
+
}
|
|
589
|
+
if (!dependenciesManifest || !dependenciesManifest.routes) {
|
|
590
|
+
return components;
|
|
591
|
+
}
|
|
592
|
+
const routeDeps = dependenciesManifest.routes[routePattern];
|
|
593
|
+
if (!routeDeps) {
|
|
594
|
+
return components;
|
|
595
|
+
}
|
|
596
|
+
const isPageClientComponent = routeDeps.isPageClientComponent || false;
|
|
597
|
+
const pageFilePath = routeDeps.pageFilePath || (routePattern === "/" ? "app/page.tsx" : `app${routePattern}/page.tsx`);
|
|
598
|
+
const isLayoutClientComponent = routeDeps.isLayoutClientComponent ? routeDeps.isLayoutClientComponent.slice(0, components.layouts.length) : new Array(components.layouts.length).fill(false);
|
|
599
|
+
const layoutFilePaths = routeDeps.layoutFilePaths || [];
|
|
600
|
+
const clientComponentLayoutPaths = new Array(components.layouts.length).fill(void 0);
|
|
601
|
+
if (routeDeps.isLayoutClientComponent && routeDeps.layoutFilePaths) {
|
|
602
|
+
let layoutFilePathIndex = 0;
|
|
603
|
+
for (let i = 0; i < isLayoutClientComponent.length; i++) {
|
|
604
|
+
if (isLayoutClientComponent[i] && layoutFilePathIndex < routeDeps.layoutFilePaths.length) {
|
|
605
|
+
clientComponentLayoutPaths[i] = routeDeps.layoutFilePaths[layoutFilePathIndex];
|
|
606
|
+
layoutFilePathIndex++;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return {
|
|
611
|
+
...components,
|
|
612
|
+
isPageClientComponent,
|
|
613
|
+
isLayoutClientComponent,
|
|
614
|
+
clientComponentFilePaths: {
|
|
615
|
+
page: isPageClientComponent ? pageFilePath : void 0,
|
|
616
|
+
layouts: clientComponentLayoutPaths.some((p) => p !== void 0) ? clientComponentLayoutPaths : void 0
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
}
|
|
471
620
|
async function handleErrorRoute(nextUrl, json, errorRoute, setState) {
|
|
472
621
|
try {
|
|
473
|
-
const
|
|
622
|
+
const loadedComponents = await errorRoute.load();
|
|
623
|
+
const components = detectClientComponents(errorRoute.pattern, loadedComponents);
|
|
474
624
|
let theme = "light";
|
|
475
625
|
if (typeof document !== "undefined") {
|
|
476
626
|
const cookieMatch = document.cookie.match(/theme=([^;]+)/);
|
|
@@ -591,7 +741,8 @@ async function handleNotFoundRoute(nextUrl, json, notFoundRoute, setState) {
|
|
|
591
741
|
};
|
|
592
742
|
setRouterData(routerData);
|
|
593
743
|
if (notFoundRoute) {
|
|
594
|
-
const
|
|
744
|
+
const loadedComponents = await notFoundRoute.load();
|
|
745
|
+
const components = detectClientComponents(notFoundRoute.pattern, loadedComponents);
|
|
595
746
|
setState({
|
|
596
747
|
url: nextUrl,
|
|
597
748
|
route: notFoundRoute,
|
|
@@ -676,9 +827,10 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
676
827
|
};
|
|
677
828
|
setRouterData(routerData);
|
|
678
829
|
const prefetched = prefetchedRoutes.get(matched.route);
|
|
679
|
-
const
|
|
830
|
+
const loadedComponents = prefetched ? await prefetched : await matched.route.load();
|
|
831
|
+
const components = detectClientComponents(matched.route.pattern, loadedComponents);
|
|
680
832
|
if (!prefetched) {
|
|
681
|
-
prefetchedRoutes.set(matched.route, Promise.resolve(
|
|
833
|
+
prefetchedRoutes.set(matched.route, Promise.resolve(loadedComponents));
|
|
682
834
|
}
|
|
683
835
|
window.scrollTo({
|
|
684
836
|
top: 0,
|
|
@@ -840,8 +992,8 @@ function createPopStateHandler(navigate2) {
|
|
|
840
992
|
}
|
|
841
993
|
|
|
842
994
|
// modules/runtime/client/RouterContext.tsx
|
|
843
|
-
var
|
|
844
|
-
var RouterContext = (0,
|
|
995
|
+
var import_react2 = require("react");
|
|
996
|
+
var RouterContext = (0, import_react2.createContext)(null);
|
|
845
997
|
|
|
846
998
|
// modules/runtime/client/AppShell.tsx
|
|
847
999
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -851,14 +1003,14 @@ function AppShell({
|
|
|
851
1003
|
notFoundRoute,
|
|
852
1004
|
errorRoute
|
|
853
1005
|
}) {
|
|
854
|
-
const [state, setState] = (0,
|
|
855
|
-
const handlersRef = (0,
|
|
1006
|
+
const [state, setState] = (0, import_react3.useState)(initialState);
|
|
1007
|
+
const handlersRef = (0, import_react3.useRef)({
|
|
856
1008
|
setState,
|
|
857
1009
|
routes,
|
|
858
1010
|
notFoundRoute,
|
|
859
1011
|
errorRoute
|
|
860
1012
|
});
|
|
861
|
-
(0,
|
|
1013
|
+
(0, import_react3.useEffect)(() => {
|
|
862
1014
|
handlersRef.current = {
|
|
863
1015
|
setState,
|
|
864
1016
|
routes,
|
|
@@ -866,7 +1018,7 @@ function AppShell({
|
|
|
866
1018
|
errorRoute
|
|
867
1019
|
};
|
|
868
1020
|
}, [routes, notFoundRoute, errorRoute]);
|
|
869
|
-
const handleNavigate = (0,
|
|
1021
|
+
const handleNavigate = (0, import_react3.useCallback)(
|
|
870
1022
|
async (nextUrl, options) => {
|
|
871
1023
|
await navigate(nextUrl, handlersRef.current, {
|
|
872
1024
|
revalidate: options?.revalidate
|
|
@@ -874,7 +1026,7 @@ function AppShell({
|
|
|
874
1026
|
},
|
|
875
1027
|
[]
|
|
876
1028
|
);
|
|
877
|
-
(0,
|
|
1029
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
878
1030
|
if (typeof window !== "undefined") {
|
|
879
1031
|
window[ROUTER_NAVIGATE_KEY] = handleNavigate;
|
|
880
1032
|
return () => {
|
|
@@ -882,7 +1034,7 @@ function AppShell({
|
|
|
882
1034
|
};
|
|
883
1035
|
}
|
|
884
1036
|
}, [handleNavigate]);
|
|
885
|
-
(0,
|
|
1037
|
+
(0, import_react3.useEffect)(() => {
|
|
886
1038
|
let isMounted = true;
|
|
887
1039
|
async function handleNavigateInternal(nextUrl, options) {
|
|
888
1040
|
if (!isMounted) return;
|
|
@@ -901,7 +1053,7 @@ function AppShell({
|
|
|
901
1053
|
window.removeEventListener("mouseover", handleHover, false);
|
|
902
1054
|
};
|
|
903
1055
|
}, [routes, notFoundRoute]);
|
|
904
|
-
(0,
|
|
1056
|
+
(0, import_react3.useEffect)(() => {
|
|
905
1057
|
const handleDataRefresh = () => {
|
|
906
1058
|
const freshData = window[WINDOW_DATA_KEY];
|
|
907
1059
|
if (!freshData) return;
|
|
@@ -1015,6 +1167,42 @@ function setupHotReload() {
|
|
|
1015
1167
|
|
|
1016
1168
|
// modules/runtime/client/bootstrap.tsx
|
|
1017
1169
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1170
|
+
function detectClientComponents2(routePattern, components) {
|
|
1171
|
+
let dependenciesManifest = null;
|
|
1172
|
+
if (typeof window !== "undefined" && window.__LOLY_ROUTE_DEPENDENCIES__) {
|
|
1173
|
+
dependenciesManifest = window.__LOLY_ROUTE_DEPENDENCIES__;
|
|
1174
|
+
}
|
|
1175
|
+
if (!dependenciesManifest || !dependenciesManifest.routes) {
|
|
1176
|
+
return components;
|
|
1177
|
+
}
|
|
1178
|
+
const routeDeps = dependenciesManifest.routes[routePattern];
|
|
1179
|
+
if (!routeDeps) {
|
|
1180
|
+
return components;
|
|
1181
|
+
}
|
|
1182
|
+
const isPageClientComponent = routeDeps.isPageClientComponent || false;
|
|
1183
|
+
const pageFilePath = routeDeps.pageFilePath || (routePattern === "/" ? "app/page.tsx" : `app${routePattern}/page.tsx`);
|
|
1184
|
+
const isLayoutClientComponent = routeDeps.isLayoutClientComponent ? routeDeps.isLayoutClientComponent.slice(0, components.layouts.length) : new Array(components.layouts.length).fill(false);
|
|
1185
|
+
const layoutFilePaths = routeDeps.layoutFilePaths || [];
|
|
1186
|
+
const clientComponentLayoutPaths = new Array(components.layouts.length).fill(void 0);
|
|
1187
|
+
if (routeDeps.isLayoutClientComponent && routeDeps.layoutFilePaths) {
|
|
1188
|
+
let layoutFilePathIndex = 0;
|
|
1189
|
+
for (let i = 0; i < isLayoutClientComponent.length; i++) {
|
|
1190
|
+
if (isLayoutClientComponent[i] && layoutFilePathIndex < routeDeps.layoutFilePaths.length) {
|
|
1191
|
+
clientComponentLayoutPaths[i] = routeDeps.layoutFilePaths[layoutFilePathIndex];
|
|
1192
|
+
layoutFilePathIndex++;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
return {
|
|
1197
|
+
...components,
|
|
1198
|
+
isPageClientComponent,
|
|
1199
|
+
isLayoutClientComponent,
|
|
1200
|
+
clientComponentFilePaths: {
|
|
1201
|
+
page: isPageClientComponent ? pageFilePath : void 0,
|
|
1202
|
+
layouts: clientComponentLayoutPaths.some((p) => p !== void 0) ? clientComponentLayoutPaths : void 0
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1018
1206
|
async function loadInitialRoute(initialUrl, initialData, routes, notFoundRoute, errorRoute) {
|
|
1019
1207
|
const isInitialNotFound = initialData?.notFound === true;
|
|
1020
1208
|
const isInitialError = initialData?.error === true;
|
|
@@ -1024,21 +1212,25 @@ async function loadInitialRoute(initialUrl, initialData, routes, notFoundRoute,
|
|
|
1024
1212
|
if (isInitialError && errorRoute) {
|
|
1025
1213
|
initialRoute = errorRoute;
|
|
1026
1214
|
initialParams = initialData?.params ?? {};
|
|
1027
|
-
|
|
1215
|
+
const loaded = await errorRoute.load();
|
|
1216
|
+
initialComponents = detectClientComponents2(errorRoute.pattern, loaded);
|
|
1028
1217
|
} else if (isInitialNotFound && notFoundRoute) {
|
|
1029
1218
|
initialRoute = notFoundRoute;
|
|
1030
1219
|
initialParams = {};
|
|
1031
|
-
|
|
1220
|
+
const loaded = await notFoundRoute.load();
|
|
1221
|
+
initialComponents = detectClientComponents2(notFoundRoute.pattern, loaded);
|
|
1032
1222
|
} else {
|
|
1033
1223
|
const match = matchRouteClient(initialUrl, routes);
|
|
1034
1224
|
if (match) {
|
|
1035
1225
|
initialRoute = match.route;
|
|
1036
1226
|
initialParams = match.params;
|
|
1037
|
-
|
|
1227
|
+
const loaded = await match.route.load();
|
|
1228
|
+
initialComponents = detectClientComponents2(match.route.pattern, loaded);
|
|
1038
1229
|
} else if (notFoundRoute) {
|
|
1039
1230
|
initialRoute = notFoundRoute;
|
|
1040
1231
|
initialParams = {};
|
|
1041
|
-
|
|
1232
|
+
const loaded = await notFoundRoute.load();
|
|
1233
|
+
initialComponents = detectClientComponents2(notFoundRoute.pattern, loaded);
|
|
1042
1234
|
} else {
|
|
1043
1235
|
console.warn(
|
|
1044
1236
|
`[client] No route match found for ${initialUrl}. Available routes:`,
|
|
@@ -1054,6 +1246,12 @@ async function loadInitialRoute(initialUrl, initialData, routes, notFoundRoute,
|
|
|
1054
1246
|
props: initialData?.props ?? {}
|
|
1055
1247
|
};
|
|
1056
1248
|
}
|
|
1249
|
+
function getRouteDependencies(routePattern) {
|
|
1250
|
+
if (typeof window === "undefined") return null;
|
|
1251
|
+
const deps = window.__LOLY_ROUTE_DEPENDENCIES__;
|
|
1252
|
+
if (!deps || !deps.routes) return null;
|
|
1253
|
+
return deps.routes[routePattern] || null;
|
|
1254
|
+
}
|
|
1057
1255
|
function initializeRouterData(initialUrl, initialData) {
|
|
1058
1256
|
let routerData = getRouterData();
|
|
1059
1257
|
if (!routerData) {
|
|
@@ -1083,7 +1281,7 @@ async function hydrateInitialRoute(container, initialUrl, initialData, routes, n
|
|
|
1083
1281
|
console.warn("[client] Error applying metadata:", metadataError);
|
|
1084
1282
|
}
|
|
1085
1283
|
}
|
|
1086
|
-
(0,
|
|
1284
|
+
(0, import_client2.hydrateRoot)(
|
|
1087
1285
|
container,
|
|
1088
1286
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1089
1287
|
AppShell,
|
|
@@ -1125,6 +1323,39 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
1125
1323
|
}
|
|
1126
1324
|
const routerPathname = initialData?.pathname || window.location.pathname;
|
|
1127
1325
|
initializeRouterData(routerPathname + window.location.search, initialData);
|
|
1326
|
+
const routePattern = initialData?.pathname || window.location.pathname;
|
|
1327
|
+
const routeDeps = getRouteDependencies(routePattern);
|
|
1328
|
+
const hasClientIslands = !!routeDeps && (routeDeps.isPageClientComponent === true || routeDeps.isLayoutClientComponent && routeDeps.isLayoutClientComponent.some((v) => v) || routeDeps.directClientComponents && routeDeps.directClientComponents.length > 0);
|
|
1329
|
+
const initialState = await loadInitialRoute(
|
|
1330
|
+
initialUrl,
|
|
1331
|
+
initialData,
|
|
1332
|
+
routes,
|
|
1333
|
+
notFoundRoute,
|
|
1334
|
+
errorRoute
|
|
1335
|
+
);
|
|
1336
|
+
if (initialData?.metadata) {
|
|
1337
|
+
try {
|
|
1338
|
+
applyMetadata(initialData.metadata);
|
|
1339
|
+
} catch (metadataError) {
|
|
1340
|
+
console.warn("[client] Error applying metadata:", metadataError);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
if (hasClientIslands) {
|
|
1344
|
+
container.innerHTML = "";
|
|
1345
|
+
const root = (0, import_client2.createRoot)(container);
|
|
1346
|
+
root.render(
|
|
1347
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1348
|
+
AppShell,
|
|
1349
|
+
{
|
|
1350
|
+
initialState,
|
|
1351
|
+
routes,
|
|
1352
|
+
notFoundRoute,
|
|
1353
|
+
errorRoute
|
|
1354
|
+
}
|
|
1355
|
+
)
|
|
1356
|
+
);
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1128
1359
|
await hydrateInitialRoute(
|
|
1129
1360
|
container,
|
|
1130
1361
|
initialUrl,
|
|
@@ -1133,6 +1364,19 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
1133
1364
|
notFoundRoute,
|
|
1134
1365
|
errorRoute
|
|
1135
1366
|
);
|
|
1367
|
+
try {
|
|
1368
|
+
await new Promise((resolve) => {
|
|
1369
|
+
if (typeof queueMicrotask !== "undefined") {
|
|
1370
|
+
queueMicrotask(resolve);
|
|
1371
|
+
} else {
|
|
1372
|
+
setTimeout(resolve, 0);
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1375
|
+
const { mountClientIslands: mountClientIslands2 } = await Promise.resolve().then(() => (init_mount_client_islands(), mount_client_islands_exports));
|
|
1376
|
+
await mountClientIslands2(container);
|
|
1377
|
+
} catch (error) {
|
|
1378
|
+
console.warn("[client] Failed to mount client component islands:", error);
|
|
1379
|
+
}
|
|
1136
1380
|
} catch (error) {
|
|
1137
1381
|
console.error("\n\u274C [client] Fatal error during bootstrap:");
|
|
1138
1382
|
console.error(error);
|