@lolyjs/core 0.2.0-alpha.18 → 0.2.0-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +57 -22
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +57 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +152 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +152 -42
- package/dist/index.js.map +1 -1
- package/dist/react/cache.cjs +82 -32
- package/dist/react/cache.cjs.map +1 -1
- package/dist/react/cache.d.mts +6 -19
- package/dist/react/cache.d.ts +6 -19
- package/dist/react/cache.js +83 -33
- package/dist/react/cache.js.map +1 -1
- package/dist/react/components.cjs +10 -8
- package/dist/react/components.cjs.map +1 -1
- package/dist/react/components.js +10 -8
- 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/runtime.cjs +95 -20
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +95 -20
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -15034,7 +15034,7 @@ async function runRouteServerHook(route, ctx) {
|
|
|
15034
15034
|
}
|
|
15035
15035
|
|
|
15036
15036
|
// modules/server/handlers/response.ts
|
|
15037
|
-
function handleDataResponse(res, loaderResult, theme) {
|
|
15037
|
+
function handleDataResponse(res, loaderResult, theme, layoutProps, pageProps, error, message) {
|
|
15038
15038
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
15039
15039
|
if (loaderResult.redirect) {
|
|
15040
15040
|
res.statusCode = 200;
|
|
@@ -15046,14 +15046,26 @@ function handleDataResponse(res, loaderResult, theme) {
|
|
|
15046
15046
|
res.end(JSON.stringify({ notFound: true }));
|
|
15047
15047
|
return;
|
|
15048
15048
|
}
|
|
15049
|
-
|
|
15050
|
-
|
|
15051
|
-
|
|
15052
|
-
|
|
15053
|
-
|
|
15054
|
-
|
|
15055
|
-
|
|
15056
|
-
|
|
15049
|
+
const response = {
|
|
15050
|
+
// Combined props for backward compatibility
|
|
15051
|
+
props: loaderResult.props ?? {},
|
|
15052
|
+
metadata: loaderResult.metadata ?? null,
|
|
15053
|
+
theme: loaderResult.theme ?? theme ?? null
|
|
15054
|
+
};
|
|
15055
|
+
if (layoutProps !== void 0 && layoutProps !== null) {
|
|
15056
|
+
response.layoutProps = layoutProps;
|
|
15057
|
+
}
|
|
15058
|
+
if (pageProps !== void 0 && pageProps !== null) {
|
|
15059
|
+
response.pageProps = pageProps;
|
|
15060
|
+
}
|
|
15061
|
+
if (error !== void 0) {
|
|
15062
|
+
response.error = error;
|
|
15063
|
+
}
|
|
15064
|
+
if (message !== void 0) {
|
|
15065
|
+
response.message = message;
|
|
15066
|
+
}
|
|
15067
|
+
res.statusCode = error ? 500 : 200;
|
|
15068
|
+
res.end(JSON.stringify(response));
|
|
15057
15069
|
}
|
|
15058
15070
|
function handleRedirect(res, redirect) {
|
|
15059
15071
|
const { destination, permanent } = redirect;
|
|
@@ -15191,6 +15203,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15191
15203
|
const clientCssPath = env === "dev" ? "/static/client.css" : projectRoot ? getClientCssPath(projectRoot) : "/static/client.css";
|
|
15192
15204
|
const assetManifest = env === "prod" && projectRoot ? loadAssetManifest(projectRoot) : null;
|
|
15193
15205
|
const isDataReq = isDataRequest(req);
|
|
15206
|
+
const skipLayoutHooks = isDataReq && req.headers["x-skip-layout-hooks"] === "true";
|
|
15194
15207
|
if (env === "prod" && ssgOutDir) {
|
|
15195
15208
|
if (isDataReq) {
|
|
15196
15209
|
if (tryServeSsgData(res, ssgOutDir, urlPath)) {
|
|
@@ -15214,7 +15227,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15214
15227
|
locals: {}
|
|
15215
15228
|
};
|
|
15216
15229
|
const layoutProps2 = {};
|
|
15217
|
-
if (notFoundPage.layoutServerHooks && notFoundPage.layoutServerHooks.length > 0) {
|
|
15230
|
+
if (!skipLayoutHooks && notFoundPage.layoutServerHooks && notFoundPage.layoutServerHooks.length > 0) {
|
|
15218
15231
|
for (let i = 0; i < notFoundPage.layoutServerHooks.length; i++) {
|
|
15219
15232
|
const layoutServerHook = notFoundPage.layoutServerHooks[i];
|
|
15220
15233
|
if (layoutServerHook) {
|
|
@@ -15249,6 +15262,17 @@ async function handlePageRequestInternal(options) {
|
|
|
15249
15262
|
...loaderResult2,
|
|
15250
15263
|
props: combinedProps2
|
|
15251
15264
|
};
|
|
15265
|
+
if (isDataReq) {
|
|
15266
|
+
const pagePropsOnly = loaderResult2.props || {};
|
|
15267
|
+
handleDataResponse(
|
|
15268
|
+
res,
|
|
15269
|
+
combinedLoaderResult2,
|
|
15270
|
+
theme,
|
|
15271
|
+
skipLayoutHooks ? null : Object.keys(layoutProps2).length > 0 ? layoutProps2 : null,
|
|
15272
|
+
pagePropsOnly
|
|
15273
|
+
);
|
|
15274
|
+
return;
|
|
15275
|
+
}
|
|
15252
15276
|
const initialData2 = buildInitialData(urlPath, {}, combinedLoaderResult2);
|
|
15253
15277
|
const appTree2 = buildAppTree(notFoundPage, {}, initialData2.props);
|
|
15254
15278
|
initialData2.notFound = true;
|
|
@@ -15320,7 +15344,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15320
15344
|
const layoutProps = {};
|
|
15321
15345
|
const layoutMetadata = [];
|
|
15322
15346
|
const reqLogger = getRequestLogger(req);
|
|
15323
|
-
if (route.layoutServerHooks && route.layoutServerHooks.length > 0) {
|
|
15347
|
+
if (!skipLayoutHooks && route.layoutServerHooks && route.layoutServerHooks.length > 0) {
|
|
15324
15348
|
for (let i = 0; i < route.layoutServerHooks.length; i++) {
|
|
15325
15349
|
const layoutServerHook = route.layoutServerHooks[i];
|
|
15326
15350
|
if (layoutServerHook) {
|
|
@@ -15404,7 +15428,14 @@ async function handlePageRequestInternal(options) {
|
|
|
15404
15428
|
metadata: combinedMetadata
|
|
15405
15429
|
};
|
|
15406
15430
|
if (isDataReq) {
|
|
15407
|
-
|
|
15431
|
+
const pagePropsOnly = loaderResult.props || {};
|
|
15432
|
+
handleDataResponse(
|
|
15433
|
+
res,
|
|
15434
|
+
combinedLoaderResult,
|
|
15435
|
+
theme,
|
|
15436
|
+
skipLayoutHooks ? null : Object.keys(layoutProps).length > 0 ? layoutProps : null,
|
|
15437
|
+
pagePropsOnly
|
|
15438
|
+
);
|
|
15408
15439
|
return;
|
|
15409
15440
|
}
|
|
15410
15441
|
if (loaderResult.redirect) {
|
|
@@ -15498,6 +15529,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15498
15529
|
async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks, theme, projectRoot, env = "dev") {
|
|
15499
15530
|
try {
|
|
15500
15531
|
const isDataReq = isDataRequest(req);
|
|
15532
|
+
const skipLayoutHooks = isDataReq && req.headers["x-skip-layout-hooks"] === "true";
|
|
15501
15533
|
const ctx = {
|
|
15502
15534
|
req,
|
|
15503
15535
|
res,
|
|
@@ -15507,7 +15539,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
15507
15539
|
};
|
|
15508
15540
|
const layoutProps = {};
|
|
15509
15541
|
const reqLogger = getRequestLogger(req);
|
|
15510
|
-
if (errorPage.layoutServerHooks && errorPage.layoutServerHooks.length > 0) {
|
|
15542
|
+
if (!skipLayoutHooks && errorPage.layoutServerHooks && errorPage.layoutServerHooks.length > 0) {
|
|
15511
15543
|
for (let i = 0; i < errorPage.layoutServerHooks.length; i++) {
|
|
15512
15544
|
const layoutServerHook = errorPage.layoutServerHooks[i];
|
|
15513
15545
|
if (layoutServerHook) {
|
|
@@ -15545,15 +15577,18 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
15545
15577
|
const routerData = buildRouterData(req);
|
|
15546
15578
|
initialData.error = true;
|
|
15547
15579
|
if (isDataReq) {
|
|
15548
|
-
|
|
15549
|
-
|
|
15550
|
-
|
|
15551
|
-
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15555
|
-
|
|
15556
|
-
|
|
15580
|
+
const pagePropsOnly = loaderResult.props || {};
|
|
15581
|
+
handleDataResponse(
|
|
15582
|
+
res,
|
|
15583
|
+
combinedLoaderResult,
|
|
15584
|
+
theme,
|
|
15585
|
+
skipLayoutHooks ? null : Object.keys(layoutProps).length > 0 ? layoutProps : null,
|
|
15586
|
+
pagePropsOnly,
|
|
15587
|
+
true,
|
|
15588
|
+
// error flag
|
|
15589
|
+
String(error)
|
|
15590
|
+
// error message
|
|
15591
|
+
);
|
|
15557
15592
|
return;
|
|
15558
15593
|
}
|
|
15559
15594
|
const appTree = buildAppTree(errorPage, { error: String(error) }, initialData.props);
|
|
@@ -17559,12 +17594,29 @@ var APP_CONTAINER_ID2 = "__app";
|
|
|
17559
17594
|
var ROUTER_NAVIGATE_KEY = "__LOLY_ROUTER_NAVIGATE__";
|
|
17560
17595
|
|
|
17561
17596
|
// modules/runtime/client/window-data.ts
|
|
17597
|
+
var LAYOUT_PROPS_KEY = "__FW_LAYOUT_PROPS__";
|
|
17562
17598
|
function getWindowData() {
|
|
17563
17599
|
if (typeof window === "undefined") {
|
|
17564
17600
|
return null;
|
|
17565
17601
|
}
|
|
17566
17602
|
return window[WINDOW_DATA_KEY2] ?? null;
|
|
17567
17603
|
}
|
|
17604
|
+
function getPreservedLayoutProps() {
|
|
17605
|
+
if (typeof window === "undefined") {
|
|
17606
|
+
return null;
|
|
17607
|
+
}
|
|
17608
|
+
return window[LAYOUT_PROPS_KEY] ?? null;
|
|
17609
|
+
}
|
|
17610
|
+
function setPreservedLayoutProps(props) {
|
|
17611
|
+
if (typeof window === "undefined") {
|
|
17612
|
+
return;
|
|
17613
|
+
}
|
|
17614
|
+
if (props === null) {
|
|
17615
|
+
delete window[LAYOUT_PROPS_KEY];
|
|
17616
|
+
} else {
|
|
17617
|
+
window[LAYOUT_PROPS_KEY] = props;
|
|
17618
|
+
}
|
|
17619
|
+
}
|
|
17568
17620
|
function getRouterData() {
|
|
17569
17621
|
if (typeof window === "undefined") {
|
|
17570
17622
|
return null;
|
|
@@ -17900,14 +17952,16 @@ function deleteCacheEntry(key) {
|
|
|
17900
17952
|
function buildDataUrl(url) {
|
|
17901
17953
|
return url + (url.includes("?") ? "&" : "?") + "__fw_data=1";
|
|
17902
17954
|
}
|
|
17903
|
-
async function fetchRouteDataOnce(url) {
|
|
17955
|
+
async function fetchRouteDataOnce(url, skipLayoutHooks = true) {
|
|
17904
17956
|
const dataUrl = buildDataUrl(url);
|
|
17905
|
-
const
|
|
17906
|
-
|
|
17907
|
-
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17957
|
+
const headers = {
|
|
17958
|
+
"x-fw-data": "1",
|
|
17959
|
+
Accept: "application/json"
|
|
17960
|
+
};
|
|
17961
|
+
if (skipLayoutHooks) {
|
|
17962
|
+
headers["x-skip-layout-hooks"] = "true";
|
|
17963
|
+
}
|
|
17964
|
+
const res = await fetch(dataUrl, { headers });
|
|
17911
17965
|
let json = {};
|
|
17912
17966
|
try {
|
|
17913
17967
|
const text = await res.text();
|
|
@@ -17933,7 +17987,7 @@ async function getRouteData(url, options) {
|
|
|
17933
17987
|
deleteCacheEntry(key);
|
|
17934
17988
|
}
|
|
17935
17989
|
const entry = dataCache.get(key);
|
|
17936
|
-
if (entry) {
|
|
17990
|
+
if (entry && !options?.revalidate) {
|
|
17937
17991
|
if (entry.status === "fulfilled") {
|
|
17938
17992
|
updateLRU(key);
|
|
17939
17993
|
return entry.value;
|
|
@@ -17942,12 +17996,29 @@ async function getRouteData(url, options) {
|
|
|
17942
17996
|
return entry.promise;
|
|
17943
17997
|
}
|
|
17944
17998
|
}
|
|
17945
|
-
const
|
|
17946
|
-
|
|
17999
|
+
const skipLayoutHooks = !options?.revalidate;
|
|
18000
|
+
const currentEntry = dataCache.get(key);
|
|
18001
|
+
if (currentEntry && !options?.revalidate) {
|
|
18002
|
+
if (currentEntry.status === "fulfilled") {
|
|
18003
|
+
updateLRU(key);
|
|
18004
|
+
return currentEntry.value;
|
|
18005
|
+
}
|
|
18006
|
+
if (currentEntry.status === "pending") {
|
|
18007
|
+
return currentEntry.promise;
|
|
18008
|
+
}
|
|
18009
|
+
}
|
|
18010
|
+
const promise = fetchRouteDataOnce(url, skipLayoutHooks).then((value) => {
|
|
18011
|
+
const entryAfterFetch = dataCache.get(key);
|
|
18012
|
+
if (!entryAfterFetch || entryAfterFetch.status === "pending") {
|
|
18013
|
+
setCacheEntry(key, { status: "fulfilled", value });
|
|
18014
|
+
}
|
|
17947
18015
|
return value;
|
|
17948
18016
|
}).catch((error) => {
|
|
17949
18017
|
console.error("[client][cache] Error fetching route data:", error);
|
|
17950
|
-
dataCache.
|
|
18018
|
+
const entryAfterFetch = dataCache.get(key);
|
|
18019
|
+
if (!entryAfterFetch || entryAfterFetch.status === "pending") {
|
|
18020
|
+
dataCache.set(key, { status: "rejected", error });
|
|
18021
|
+
}
|
|
17951
18022
|
throw error;
|
|
17952
18023
|
});
|
|
17953
18024
|
dataCache.set(key, { status: "pending", promise });
|
|
@@ -17972,10 +18043,22 @@ async function handleErrorRoute(nextUrl, json, errorRoute, setState) {
|
|
|
17972
18043
|
} else if (json.theme) {
|
|
17973
18044
|
theme = json.theme;
|
|
17974
18045
|
}
|
|
18046
|
+
let layoutProps = {};
|
|
18047
|
+
if (json.layoutProps !== void 0 && json.layoutProps !== null) {
|
|
18048
|
+
layoutProps = json.layoutProps;
|
|
18049
|
+
setPreservedLayoutProps(layoutProps);
|
|
18050
|
+
} else {
|
|
18051
|
+
const preserved = getPreservedLayoutProps();
|
|
18052
|
+
if (preserved) {
|
|
18053
|
+
layoutProps = preserved;
|
|
18054
|
+
}
|
|
18055
|
+
}
|
|
18056
|
+
const pageProps = json.pageProps ?? json.props ?? {
|
|
18057
|
+
error: json.message || "An error occurred"
|
|
18058
|
+
};
|
|
17975
18059
|
const errorProps = {
|
|
17976
|
-
...
|
|
17977
|
-
|
|
17978
|
-
},
|
|
18060
|
+
...layoutProps,
|
|
18061
|
+
...pageProps,
|
|
17979
18062
|
theme
|
|
17980
18063
|
};
|
|
17981
18064
|
const windowData = {
|
|
@@ -18032,8 +18115,20 @@ async function handleNotFoundRoute(nextUrl, json, notFoundRoute, setState) {
|
|
|
18032
18115
|
} else if (json.theme) {
|
|
18033
18116
|
theme = json.theme;
|
|
18034
18117
|
}
|
|
18118
|
+
let layoutProps = {};
|
|
18119
|
+
if (json.layoutProps !== void 0 && json.layoutProps !== null) {
|
|
18120
|
+
layoutProps = json.layoutProps;
|
|
18121
|
+
setPreservedLayoutProps(layoutProps);
|
|
18122
|
+
} else {
|
|
18123
|
+
const preserved = getPreservedLayoutProps();
|
|
18124
|
+
if (preserved) {
|
|
18125
|
+
layoutProps = preserved;
|
|
18126
|
+
}
|
|
18127
|
+
}
|
|
18128
|
+
const pageProps = json.pageProps ?? json.props ?? {};
|
|
18035
18129
|
const notFoundProps = {
|
|
18036
|
-
...
|
|
18130
|
+
...layoutProps,
|
|
18131
|
+
...pageProps,
|
|
18037
18132
|
theme
|
|
18038
18133
|
};
|
|
18039
18134
|
const windowData = {
|
|
@@ -18090,8 +18185,20 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
18090
18185
|
} else if (json.theme) {
|
|
18091
18186
|
theme = json.theme;
|
|
18092
18187
|
}
|
|
18093
|
-
|
|
18094
|
-
|
|
18188
|
+
let layoutProps = {};
|
|
18189
|
+
if (json.layoutProps !== void 0 && json.layoutProps !== null) {
|
|
18190
|
+
layoutProps = json.layoutProps;
|
|
18191
|
+
setPreservedLayoutProps(layoutProps);
|
|
18192
|
+
} else {
|
|
18193
|
+
const preserved = getPreservedLayoutProps();
|
|
18194
|
+
if (preserved) {
|
|
18195
|
+
layoutProps = preserved;
|
|
18196
|
+
}
|
|
18197
|
+
}
|
|
18198
|
+
const pageProps = json.pageProps ?? json.props ?? {};
|
|
18199
|
+
const combinedProps = {
|
|
18200
|
+
...layoutProps,
|
|
18201
|
+
...pageProps,
|
|
18095
18202
|
theme
|
|
18096
18203
|
// Always include theme
|
|
18097
18204
|
};
|
|
@@ -18103,7 +18210,7 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
18103
18210
|
const windowData = {
|
|
18104
18211
|
pathname: nextUrl,
|
|
18105
18212
|
params: matched.params,
|
|
18106
|
-
props:
|
|
18213
|
+
props: combinedProps,
|
|
18107
18214
|
metadata: json.metadata ?? null,
|
|
18108
18215
|
theme,
|
|
18109
18216
|
notFound: false,
|
|
@@ -18131,7 +18238,7 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
18131
18238
|
route: matched.route,
|
|
18132
18239
|
params: matched.params,
|
|
18133
18240
|
components,
|
|
18134
|
-
props:
|
|
18241
|
+
props: combinedProps
|
|
18135
18242
|
});
|
|
18136
18243
|
return true;
|
|
18137
18244
|
}
|
|
@@ -18364,7 +18471,7 @@ function AppShell({
|
|
|
18364
18471
|
return () => {
|
|
18365
18472
|
window.removeEventListener("fw-data-refresh", handleDataRefresh);
|
|
18366
18473
|
};
|
|
18367
|
-
}, [
|
|
18474
|
+
}, []);
|
|
18368
18475
|
const isError = state.route === errorRoute;
|
|
18369
18476
|
const isNotFound = state.route === notFoundRoute;
|
|
18370
18477
|
const routeType = isError ? "error" : isNotFound ? "notfound" : "normal";
|
|
@@ -18563,6 +18670,9 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
18563
18670
|
}
|
|
18564
18671
|
const initialData = getWindowData();
|
|
18565
18672
|
const initialUrl = window.location.pathname + window.location.search;
|
|
18673
|
+
if (initialData?.props) {
|
|
18674
|
+
setPreservedLayoutProps(initialData.props);
|
|
18675
|
+
}
|
|
18566
18676
|
initializeRouterData(initialUrl, initialData);
|
|
18567
18677
|
await hydrateInitialRoute(
|
|
18568
18678
|
container,
|