@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.js
CHANGED
|
@@ -15001,7 +15001,7 @@ async function runRouteServerHook(route, ctx) {
|
|
|
15001
15001
|
}
|
|
15002
15002
|
|
|
15003
15003
|
// modules/server/handlers/response.ts
|
|
15004
|
-
function handleDataResponse(res, loaderResult, theme) {
|
|
15004
|
+
function handleDataResponse(res, loaderResult, theme, layoutProps, pageProps, error, message) {
|
|
15005
15005
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
15006
15006
|
if (loaderResult.redirect) {
|
|
15007
15007
|
res.statusCode = 200;
|
|
@@ -15013,14 +15013,26 @@ function handleDataResponse(res, loaderResult, theme) {
|
|
|
15013
15013
|
res.end(JSON.stringify({ notFound: true }));
|
|
15014
15014
|
return;
|
|
15015
15015
|
}
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
|
|
15019
|
-
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
|
|
15016
|
+
const response = {
|
|
15017
|
+
// Combined props for backward compatibility
|
|
15018
|
+
props: loaderResult.props ?? {},
|
|
15019
|
+
metadata: loaderResult.metadata ?? null,
|
|
15020
|
+
theme: loaderResult.theme ?? theme ?? null
|
|
15021
|
+
};
|
|
15022
|
+
if (layoutProps !== void 0 && layoutProps !== null) {
|
|
15023
|
+
response.layoutProps = layoutProps;
|
|
15024
|
+
}
|
|
15025
|
+
if (pageProps !== void 0 && pageProps !== null) {
|
|
15026
|
+
response.pageProps = pageProps;
|
|
15027
|
+
}
|
|
15028
|
+
if (error !== void 0) {
|
|
15029
|
+
response.error = error;
|
|
15030
|
+
}
|
|
15031
|
+
if (message !== void 0) {
|
|
15032
|
+
response.message = message;
|
|
15033
|
+
}
|
|
15034
|
+
res.statusCode = error ? 500 : 200;
|
|
15035
|
+
res.end(JSON.stringify(response));
|
|
15024
15036
|
}
|
|
15025
15037
|
function handleRedirect(res, redirect) {
|
|
15026
15038
|
const { destination, permanent } = redirect;
|
|
@@ -15158,6 +15170,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15158
15170
|
const clientCssPath = env === "dev" ? "/static/client.css" : projectRoot ? getClientCssPath(projectRoot) : "/static/client.css";
|
|
15159
15171
|
const assetManifest = env === "prod" && projectRoot ? loadAssetManifest(projectRoot) : null;
|
|
15160
15172
|
const isDataReq = isDataRequest(req);
|
|
15173
|
+
const skipLayoutHooks = isDataReq && req.headers["x-skip-layout-hooks"] === "true";
|
|
15161
15174
|
if (env === "prod" && ssgOutDir) {
|
|
15162
15175
|
if (isDataReq) {
|
|
15163
15176
|
if (tryServeSsgData(res, ssgOutDir, urlPath)) {
|
|
@@ -15181,7 +15194,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15181
15194
|
locals: {}
|
|
15182
15195
|
};
|
|
15183
15196
|
const layoutProps2 = {};
|
|
15184
|
-
if (notFoundPage.layoutServerHooks && notFoundPage.layoutServerHooks.length > 0) {
|
|
15197
|
+
if (!skipLayoutHooks && notFoundPage.layoutServerHooks && notFoundPage.layoutServerHooks.length > 0) {
|
|
15185
15198
|
for (let i = 0; i < notFoundPage.layoutServerHooks.length; i++) {
|
|
15186
15199
|
const layoutServerHook = notFoundPage.layoutServerHooks[i];
|
|
15187
15200
|
if (layoutServerHook) {
|
|
@@ -15216,6 +15229,17 @@ async function handlePageRequestInternal(options) {
|
|
|
15216
15229
|
...loaderResult2,
|
|
15217
15230
|
props: combinedProps2
|
|
15218
15231
|
};
|
|
15232
|
+
if (isDataReq) {
|
|
15233
|
+
const pagePropsOnly = loaderResult2.props || {};
|
|
15234
|
+
handleDataResponse(
|
|
15235
|
+
res,
|
|
15236
|
+
combinedLoaderResult2,
|
|
15237
|
+
theme,
|
|
15238
|
+
skipLayoutHooks ? null : Object.keys(layoutProps2).length > 0 ? layoutProps2 : null,
|
|
15239
|
+
pagePropsOnly
|
|
15240
|
+
);
|
|
15241
|
+
return;
|
|
15242
|
+
}
|
|
15219
15243
|
const initialData2 = buildInitialData(urlPath, {}, combinedLoaderResult2);
|
|
15220
15244
|
const appTree2 = buildAppTree(notFoundPage, {}, initialData2.props);
|
|
15221
15245
|
initialData2.notFound = true;
|
|
@@ -15287,7 +15311,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15287
15311
|
const layoutProps = {};
|
|
15288
15312
|
const layoutMetadata = [];
|
|
15289
15313
|
const reqLogger = getRequestLogger(req);
|
|
15290
|
-
if (route.layoutServerHooks && route.layoutServerHooks.length > 0) {
|
|
15314
|
+
if (!skipLayoutHooks && route.layoutServerHooks && route.layoutServerHooks.length > 0) {
|
|
15291
15315
|
for (let i = 0; i < route.layoutServerHooks.length; i++) {
|
|
15292
15316
|
const layoutServerHook = route.layoutServerHooks[i];
|
|
15293
15317
|
if (layoutServerHook) {
|
|
@@ -15371,7 +15395,14 @@ async function handlePageRequestInternal(options) {
|
|
|
15371
15395
|
metadata: combinedMetadata
|
|
15372
15396
|
};
|
|
15373
15397
|
if (isDataReq) {
|
|
15374
|
-
|
|
15398
|
+
const pagePropsOnly = loaderResult.props || {};
|
|
15399
|
+
handleDataResponse(
|
|
15400
|
+
res,
|
|
15401
|
+
combinedLoaderResult,
|
|
15402
|
+
theme,
|
|
15403
|
+
skipLayoutHooks ? null : Object.keys(layoutProps).length > 0 ? layoutProps : null,
|
|
15404
|
+
pagePropsOnly
|
|
15405
|
+
);
|
|
15375
15406
|
return;
|
|
15376
15407
|
}
|
|
15377
15408
|
if (loaderResult.redirect) {
|
|
@@ -15465,6 +15496,7 @@ async function handlePageRequestInternal(options) {
|
|
|
15465
15496
|
async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks, theme, projectRoot, env = "dev") {
|
|
15466
15497
|
try {
|
|
15467
15498
|
const isDataReq = isDataRequest(req);
|
|
15499
|
+
const skipLayoutHooks = isDataReq && req.headers["x-skip-layout-hooks"] === "true";
|
|
15468
15500
|
const ctx = {
|
|
15469
15501
|
req,
|
|
15470
15502
|
res,
|
|
@@ -15474,7 +15506,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
15474
15506
|
};
|
|
15475
15507
|
const layoutProps = {};
|
|
15476
15508
|
const reqLogger = getRequestLogger(req);
|
|
15477
|
-
if (errorPage.layoutServerHooks && errorPage.layoutServerHooks.length > 0) {
|
|
15509
|
+
if (!skipLayoutHooks && errorPage.layoutServerHooks && errorPage.layoutServerHooks.length > 0) {
|
|
15478
15510
|
for (let i = 0; i < errorPage.layoutServerHooks.length; i++) {
|
|
15479
15511
|
const layoutServerHook = errorPage.layoutServerHooks[i];
|
|
15480
15512
|
if (layoutServerHook) {
|
|
@@ -15512,15 +15544,18 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
15512
15544
|
const routerData = buildRouterData(req);
|
|
15513
15545
|
initialData.error = true;
|
|
15514
15546
|
if (isDataReq) {
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
|
|
15521
|
-
|
|
15522
|
-
|
|
15523
|
-
|
|
15547
|
+
const pagePropsOnly = loaderResult.props || {};
|
|
15548
|
+
handleDataResponse(
|
|
15549
|
+
res,
|
|
15550
|
+
combinedLoaderResult,
|
|
15551
|
+
theme,
|
|
15552
|
+
skipLayoutHooks ? null : Object.keys(layoutProps).length > 0 ? layoutProps : null,
|
|
15553
|
+
pagePropsOnly,
|
|
15554
|
+
true,
|
|
15555
|
+
// error flag
|
|
15556
|
+
String(error)
|
|
15557
|
+
// error message
|
|
15558
|
+
);
|
|
15524
15559
|
return;
|
|
15525
15560
|
}
|
|
15526
15561
|
const appTree = buildAppTree(errorPage, { error: String(error) }, initialData.props);
|
|
@@ -17526,12 +17561,29 @@ var APP_CONTAINER_ID2 = "__app";
|
|
|
17526
17561
|
var ROUTER_NAVIGATE_KEY = "__LOLY_ROUTER_NAVIGATE__";
|
|
17527
17562
|
|
|
17528
17563
|
// modules/runtime/client/window-data.ts
|
|
17564
|
+
var LAYOUT_PROPS_KEY = "__FW_LAYOUT_PROPS__";
|
|
17529
17565
|
function getWindowData() {
|
|
17530
17566
|
if (typeof window === "undefined") {
|
|
17531
17567
|
return null;
|
|
17532
17568
|
}
|
|
17533
17569
|
return window[WINDOW_DATA_KEY2] ?? null;
|
|
17534
17570
|
}
|
|
17571
|
+
function getPreservedLayoutProps() {
|
|
17572
|
+
if (typeof window === "undefined") {
|
|
17573
|
+
return null;
|
|
17574
|
+
}
|
|
17575
|
+
return window[LAYOUT_PROPS_KEY] ?? null;
|
|
17576
|
+
}
|
|
17577
|
+
function setPreservedLayoutProps(props) {
|
|
17578
|
+
if (typeof window === "undefined") {
|
|
17579
|
+
return;
|
|
17580
|
+
}
|
|
17581
|
+
if (props === null) {
|
|
17582
|
+
delete window[LAYOUT_PROPS_KEY];
|
|
17583
|
+
} else {
|
|
17584
|
+
window[LAYOUT_PROPS_KEY] = props;
|
|
17585
|
+
}
|
|
17586
|
+
}
|
|
17535
17587
|
function getRouterData() {
|
|
17536
17588
|
if (typeof window === "undefined") {
|
|
17537
17589
|
return null;
|
|
@@ -17867,14 +17919,16 @@ function deleteCacheEntry(key) {
|
|
|
17867
17919
|
function buildDataUrl(url) {
|
|
17868
17920
|
return url + (url.includes("?") ? "&" : "?") + "__fw_data=1";
|
|
17869
17921
|
}
|
|
17870
|
-
async function fetchRouteDataOnce(url) {
|
|
17922
|
+
async function fetchRouteDataOnce(url, skipLayoutHooks = true) {
|
|
17871
17923
|
const dataUrl = buildDataUrl(url);
|
|
17872
|
-
const
|
|
17873
|
-
|
|
17874
|
-
|
|
17875
|
-
|
|
17876
|
-
|
|
17877
|
-
|
|
17924
|
+
const headers = {
|
|
17925
|
+
"x-fw-data": "1",
|
|
17926
|
+
Accept: "application/json"
|
|
17927
|
+
};
|
|
17928
|
+
if (skipLayoutHooks) {
|
|
17929
|
+
headers["x-skip-layout-hooks"] = "true";
|
|
17930
|
+
}
|
|
17931
|
+
const res = await fetch(dataUrl, { headers });
|
|
17878
17932
|
let json = {};
|
|
17879
17933
|
try {
|
|
17880
17934
|
const text = await res.text();
|
|
@@ -17900,7 +17954,7 @@ async function getRouteData(url, options) {
|
|
|
17900
17954
|
deleteCacheEntry(key);
|
|
17901
17955
|
}
|
|
17902
17956
|
const entry = dataCache.get(key);
|
|
17903
|
-
if (entry) {
|
|
17957
|
+
if (entry && !options?.revalidate) {
|
|
17904
17958
|
if (entry.status === "fulfilled") {
|
|
17905
17959
|
updateLRU(key);
|
|
17906
17960
|
return entry.value;
|
|
@@ -17909,12 +17963,29 @@ async function getRouteData(url, options) {
|
|
|
17909
17963
|
return entry.promise;
|
|
17910
17964
|
}
|
|
17911
17965
|
}
|
|
17912
|
-
const
|
|
17913
|
-
|
|
17966
|
+
const skipLayoutHooks = !options?.revalidate;
|
|
17967
|
+
const currentEntry = dataCache.get(key);
|
|
17968
|
+
if (currentEntry && !options?.revalidate) {
|
|
17969
|
+
if (currentEntry.status === "fulfilled") {
|
|
17970
|
+
updateLRU(key);
|
|
17971
|
+
return currentEntry.value;
|
|
17972
|
+
}
|
|
17973
|
+
if (currentEntry.status === "pending") {
|
|
17974
|
+
return currentEntry.promise;
|
|
17975
|
+
}
|
|
17976
|
+
}
|
|
17977
|
+
const promise = fetchRouteDataOnce(url, skipLayoutHooks).then((value) => {
|
|
17978
|
+
const entryAfterFetch = dataCache.get(key);
|
|
17979
|
+
if (!entryAfterFetch || entryAfterFetch.status === "pending") {
|
|
17980
|
+
setCacheEntry(key, { status: "fulfilled", value });
|
|
17981
|
+
}
|
|
17914
17982
|
return value;
|
|
17915
17983
|
}).catch((error) => {
|
|
17916
17984
|
console.error("[client][cache] Error fetching route data:", error);
|
|
17917
|
-
dataCache.
|
|
17985
|
+
const entryAfterFetch = dataCache.get(key);
|
|
17986
|
+
if (!entryAfterFetch || entryAfterFetch.status === "pending") {
|
|
17987
|
+
dataCache.set(key, { status: "rejected", error });
|
|
17988
|
+
}
|
|
17918
17989
|
throw error;
|
|
17919
17990
|
});
|
|
17920
17991
|
dataCache.set(key, { status: "pending", promise });
|
|
@@ -17939,10 +18010,22 @@ async function handleErrorRoute(nextUrl, json, errorRoute, setState) {
|
|
|
17939
18010
|
} else if (json.theme) {
|
|
17940
18011
|
theme = json.theme;
|
|
17941
18012
|
}
|
|
18013
|
+
let layoutProps = {};
|
|
18014
|
+
if (json.layoutProps !== void 0 && json.layoutProps !== null) {
|
|
18015
|
+
layoutProps = json.layoutProps;
|
|
18016
|
+
setPreservedLayoutProps(layoutProps);
|
|
18017
|
+
} else {
|
|
18018
|
+
const preserved = getPreservedLayoutProps();
|
|
18019
|
+
if (preserved) {
|
|
18020
|
+
layoutProps = preserved;
|
|
18021
|
+
}
|
|
18022
|
+
}
|
|
18023
|
+
const pageProps = json.pageProps ?? json.props ?? {
|
|
18024
|
+
error: json.message || "An error occurred"
|
|
18025
|
+
};
|
|
17942
18026
|
const errorProps = {
|
|
17943
|
-
...
|
|
17944
|
-
|
|
17945
|
-
},
|
|
18027
|
+
...layoutProps,
|
|
18028
|
+
...pageProps,
|
|
17946
18029
|
theme
|
|
17947
18030
|
};
|
|
17948
18031
|
const windowData = {
|
|
@@ -17999,8 +18082,20 @@ async function handleNotFoundRoute(nextUrl, json, notFoundRoute, setState) {
|
|
|
17999
18082
|
} else if (json.theme) {
|
|
18000
18083
|
theme = json.theme;
|
|
18001
18084
|
}
|
|
18085
|
+
let layoutProps = {};
|
|
18086
|
+
if (json.layoutProps !== void 0 && json.layoutProps !== null) {
|
|
18087
|
+
layoutProps = json.layoutProps;
|
|
18088
|
+
setPreservedLayoutProps(layoutProps);
|
|
18089
|
+
} else {
|
|
18090
|
+
const preserved = getPreservedLayoutProps();
|
|
18091
|
+
if (preserved) {
|
|
18092
|
+
layoutProps = preserved;
|
|
18093
|
+
}
|
|
18094
|
+
}
|
|
18095
|
+
const pageProps = json.pageProps ?? json.props ?? {};
|
|
18002
18096
|
const notFoundProps = {
|
|
18003
|
-
...
|
|
18097
|
+
...layoutProps,
|
|
18098
|
+
...pageProps,
|
|
18004
18099
|
theme
|
|
18005
18100
|
};
|
|
18006
18101
|
const windowData = {
|
|
@@ -18057,8 +18152,20 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
18057
18152
|
} else if (json.theme) {
|
|
18058
18153
|
theme = json.theme;
|
|
18059
18154
|
}
|
|
18060
|
-
|
|
18061
|
-
|
|
18155
|
+
let layoutProps = {};
|
|
18156
|
+
if (json.layoutProps !== void 0 && json.layoutProps !== null) {
|
|
18157
|
+
layoutProps = json.layoutProps;
|
|
18158
|
+
setPreservedLayoutProps(layoutProps);
|
|
18159
|
+
} else {
|
|
18160
|
+
const preserved = getPreservedLayoutProps();
|
|
18161
|
+
if (preserved) {
|
|
18162
|
+
layoutProps = preserved;
|
|
18163
|
+
}
|
|
18164
|
+
}
|
|
18165
|
+
const pageProps = json.pageProps ?? json.props ?? {};
|
|
18166
|
+
const combinedProps = {
|
|
18167
|
+
...layoutProps,
|
|
18168
|
+
...pageProps,
|
|
18062
18169
|
theme
|
|
18063
18170
|
// Always include theme
|
|
18064
18171
|
};
|
|
@@ -18070,7 +18177,7 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
18070
18177
|
const windowData = {
|
|
18071
18178
|
pathname: nextUrl,
|
|
18072
18179
|
params: matched.params,
|
|
18073
|
-
props:
|
|
18180
|
+
props: combinedProps,
|
|
18074
18181
|
metadata: json.metadata ?? null,
|
|
18075
18182
|
theme,
|
|
18076
18183
|
notFound: false,
|
|
@@ -18098,7 +18205,7 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
18098
18205
|
route: matched.route,
|
|
18099
18206
|
params: matched.params,
|
|
18100
18207
|
components,
|
|
18101
|
-
props:
|
|
18208
|
+
props: combinedProps
|
|
18102
18209
|
});
|
|
18103
18210
|
return true;
|
|
18104
18211
|
}
|
|
@@ -18331,7 +18438,7 @@ function AppShell({
|
|
|
18331
18438
|
return () => {
|
|
18332
18439
|
window.removeEventListener("fw-data-refresh", handleDataRefresh);
|
|
18333
18440
|
};
|
|
18334
|
-
}, [
|
|
18441
|
+
}, []);
|
|
18335
18442
|
const isError = state.route === errorRoute;
|
|
18336
18443
|
const isNotFound = state.route === notFoundRoute;
|
|
18337
18444
|
const routeType = isError ? "error" : isNotFound ? "notfound" : "normal";
|
|
@@ -18530,6 +18637,9 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
18530
18637
|
}
|
|
18531
18638
|
const initialData = getWindowData();
|
|
18532
18639
|
const initialUrl = window.location.pathname + window.location.search;
|
|
18640
|
+
if (initialData?.props) {
|
|
18641
|
+
setPreservedLayoutProps(initialData.props);
|
|
18642
|
+
}
|
|
18533
18643
|
initializeRouterData(initialUrl, initialData);
|
|
18534
18644
|
await hydrateInitialRoute(
|
|
18535
18645
|
container,
|