@lolyjs/core 0.2.0-alpha.22 → 0.2.0-alpha.24
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 +31 -21
- package/dist/cli.cjs +58 -26
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +58 -26
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +58 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +58 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11464,22 +11464,36 @@ function copyStaticAssets(projectRoot, outDir) {
|
|
|
11464
11464
|
const assetsSrc = path10.join(projectRoot, "assets");
|
|
11465
11465
|
const assetsDest = path10.join(outDir, "assets");
|
|
11466
11466
|
copyDirRecursive(assetsSrc, assetsDest);
|
|
11467
|
-
const
|
|
11467
|
+
const publicDir = path10.join(projectRoot, "public");
|
|
11468
11468
|
const candidates = ["favicon.ico", "favicon.png"];
|
|
11469
11469
|
for (const name of candidates) {
|
|
11470
|
-
const
|
|
11471
|
-
|
|
11472
|
-
let src = null;
|
|
11473
|
-
if (fs10.existsSync(fromApp)) src = fromApp;
|
|
11474
|
-
else if (fs10.existsSync(fromRoot)) src = fromRoot;
|
|
11475
|
-
if (src) {
|
|
11470
|
+
const fromPublic = path10.join(publicDir, name);
|
|
11471
|
+
if (fs10.existsSync(fromPublic)) {
|
|
11476
11472
|
const dest = path10.join(outDir, name);
|
|
11477
11473
|
ensureDir(path10.dirname(dest));
|
|
11478
|
-
fs10.copyFileSync(
|
|
11474
|
+
fs10.copyFileSync(fromPublic, dest);
|
|
11479
11475
|
break;
|
|
11480
11476
|
}
|
|
11481
11477
|
}
|
|
11482
11478
|
}
|
|
11479
|
+
function getFaviconInfo(projectRoot, staticDir = "public", isDev = false) {
|
|
11480
|
+
const candidates = [
|
|
11481
|
+
{ name: "favicon.ico", type: "image/x-icon" },
|
|
11482
|
+
{ name: "favicon.png", type: "image/png" }
|
|
11483
|
+
];
|
|
11484
|
+
const publicDir = path10.join(projectRoot, staticDir);
|
|
11485
|
+
for (const candidate of candidates) {
|
|
11486
|
+
const publicPath = path10.join(publicDir, candidate.name);
|
|
11487
|
+
if (fs10.existsSync(publicPath)) {
|
|
11488
|
+
return {
|
|
11489
|
+
path: `/${candidate.name}`,
|
|
11490
|
+
// Served at root from public/
|
|
11491
|
+
type: candidate.type
|
|
11492
|
+
};
|
|
11493
|
+
}
|
|
11494
|
+
}
|
|
11495
|
+
return null;
|
|
11496
|
+
}
|
|
11483
11497
|
function generateAssetManifest(outDir, stats) {
|
|
11484
11498
|
const manifest = {
|
|
11485
11499
|
client: {
|
|
@@ -11964,8 +11978,12 @@ function createDocumentTree(options) {
|
|
|
11964
11978
|
clientJsPath = "/static/client.js",
|
|
11965
11979
|
clientCssPath = "/static/client.css",
|
|
11966
11980
|
nonce,
|
|
11967
|
-
includeInlineScripts = true
|
|
11981
|
+
includeInlineScripts = true,
|
|
11968
11982
|
// Default true - scripts inline in body for both SSR and SSG
|
|
11983
|
+
faviconPath = FAVICON_PATH,
|
|
11984
|
+
// Default to /static/favicon.png for backward compatibility
|
|
11985
|
+
faviconType = "image/png"
|
|
11986
|
+
// Default to PNG for backward compatibility
|
|
11969
11987
|
} = options;
|
|
11970
11988
|
const metaObj = meta ?? null;
|
|
11971
11989
|
const title = metaObj?.title ?? titleFallback ?? "My Framework Dev";
|
|
@@ -12272,10 +12290,11 @@ function createDocumentTree(options) {
|
|
|
12272
12290
|
href: chunkHref,
|
|
12273
12291
|
as: "script"
|
|
12274
12292
|
}),
|
|
12275
|
-
React.createElement("link", {
|
|
12293
|
+
faviconPath && React.createElement("link", {
|
|
12294
|
+
key: "favicon",
|
|
12276
12295
|
rel: "icon",
|
|
12277
|
-
href:
|
|
12278
|
-
type: "image/png"
|
|
12296
|
+
href: faviconPath,
|
|
12297
|
+
type: faviconType || (faviconPath.endsWith(".ico") ? "image/x-icon" : "image/png")
|
|
12279
12298
|
}),
|
|
12280
12299
|
React.createElement("link", {
|
|
12281
12300
|
rel: "stylesheet",
|
|
@@ -12805,7 +12824,7 @@ async function handlePageRequest(options) {
|
|
|
12805
12824
|
const { errorPage, req, res, routeChunks, theme, projectRoot } = options;
|
|
12806
12825
|
const reqLogger = getRequestLogger(req);
|
|
12807
12826
|
if (errorPage) {
|
|
12808
|
-
await renderErrorPageWithStream(errorPage, req, res, error, routeChunks || {}, theme, projectRoot, options.env);
|
|
12827
|
+
await renderErrorPageWithStream(errorPage, req, res, error, routeChunks || {}, theme, projectRoot, options.env, options.config);
|
|
12809
12828
|
} else {
|
|
12810
12829
|
reqLogger.error("Unhandled error in page request", error, {
|
|
12811
12830
|
urlPath: options.urlPath,
|
|
@@ -12831,11 +12850,13 @@ async function handlePageRequestInternal(options) {
|
|
|
12831
12850
|
env = "dev",
|
|
12832
12851
|
ssgOutDir,
|
|
12833
12852
|
theme,
|
|
12834
|
-
projectRoot
|
|
12853
|
+
projectRoot,
|
|
12854
|
+
config
|
|
12835
12855
|
} = options;
|
|
12836
12856
|
const clientJsPath = env === "dev" ? "/static/client.js" : projectRoot ? getClientJsPath(projectRoot) : "/static/client.js";
|
|
12837
12857
|
const clientCssPath = env === "dev" ? "/static/client.css" : projectRoot ? getClientCssPath(projectRoot) : "/static/client.css";
|
|
12838
12858
|
const assetManifest = env === "prod" && projectRoot ? loadAssetManifest(projectRoot) : null;
|
|
12859
|
+
const faviconInfo = projectRoot && config ? getFaviconInfo(projectRoot, config.directories.static, env === "dev") : null;
|
|
12839
12860
|
const isDataReq = isDataRequest(req);
|
|
12840
12861
|
const skipLayoutHooks = isDataReq && req.headers["x-skip-layout-hooks"] === "true";
|
|
12841
12862
|
if (env === "prod" && ssgOutDir) {
|
|
@@ -12950,7 +12971,9 @@ async function handlePageRequestInternal(options) {
|
|
|
12950
12971
|
theme,
|
|
12951
12972
|
clientJsPath,
|
|
12952
12973
|
clientCssPath,
|
|
12953
|
-
nonce: nonce2
|
|
12974
|
+
nonce: nonce2,
|
|
12975
|
+
faviconPath: faviconInfo?.path || null,
|
|
12976
|
+
faviconType: faviconInfo?.type || null
|
|
12954
12977
|
});
|
|
12955
12978
|
let didError2 = false;
|
|
12956
12979
|
const { pipe: pipe2, abort: abort2 } = renderToPipeableStream(documentTree2, {
|
|
@@ -12965,7 +12988,7 @@ async function handlePageRequestInternal(options) {
|
|
|
12965
12988
|
const reqLogger2 = getRequestLogger(req);
|
|
12966
12989
|
reqLogger2.error("SSR shell error", err, { route: "not-found" });
|
|
12967
12990
|
if (!res.headersSent && errorPage) {
|
|
12968
|
-
renderErrorPageWithStream(errorPage, req, res, err, routeChunks, theme, projectRoot, env);
|
|
12991
|
+
renderErrorPageWithStream(errorPage, req, res, err, routeChunks, theme, projectRoot, env, config);
|
|
12969
12992
|
} else if (!res.headersSent) {
|
|
12970
12993
|
res.statusCode = 500;
|
|
12971
12994
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
@@ -13080,7 +13103,7 @@ async function handlePageRequestInternal(options) {
|
|
|
13080
13103
|
return;
|
|
13081
13104
|
} else {
|
|
13082
13105
|
if (errorPage) {
|
|
13083
|
-
await renderErrorPageWithStream(errorPage, req, res, error, routeChunks, theme, projectRoot, env);
|
|
13106
|
+
await renderErrorPageWithStream(errorPage, req, res, error, routeChunks, theme, projectRoot, env, config);
|
|
13084
13107
|
return;
|
|
13085
13108
|
} else {
|
|
13086
13109
|
throw error;
|
|
@@ -13158,7 +13181,9 @@ async function handlePageRequestInternal(options) {
|
|
|
13158
13181
|
theme,
|
|
13159
13182
|
clientJsPath,
|
|
13160
13183
|
clientCssPath,
|
|
13161
|
-
nonce
|
|
13184
|
+
nonce,
|
|
13185
|
+
faviconPath: faviconInfo?.path || null,
|
|
13186
|
+
faviconType: faviconInfo?.type || null
|
|
13162
13187
|
});
|
|
13163
13188
|
let didError = false;
|
|
13164
13189
|
const { pipe, abort } = renderToPipeableStream(documentTree, {
|
|
@@ -13206,7 +13231,7 @@ async function handlePageRequestInternal(options) {
|
|
|
13206
13231
|
abort();
|
|
13207
13232
|
});
|
|
13208
13233
|
}
|
|
13209
|
-
async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks, theme, projectRoot, env = "dev") {
|
|
13234
|
+
async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks, theme, projectRoot, env = "dev", config) {
|
|
13210
13235
|
try {
|
|
13211
13236
|
const isDataReq = isDataRequest(req);
|
|
13212
13237
|
const skipLayoutHooks = isDataReq && req.headers["x-skip-layout-hooks"] === "true";
|
|
@@ -13217,6 +13242,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
13217
13242
|
pathname: req.path,
|
|
13218
13243
|
locals: { error }
|
|
13219
13244
|
};
|
|
13245
|
+
const faviconInfo = projectRoot && config ? getFaviconInfo(projectRoot, config.directories.static, env === "dev") : null;
|
|
13220
13246
|
const layoutProps = {};
|
|
13221
13247
|
const reqLogger = getRequestLogger(req);
|
|
13222
13248
|
if (!skipLayoutHooks && errorPage.layoutServerHooks && errorPage.layoutServerHooks.length > 0) {
|
|
@@ -13322,7 +13348,9 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
13322
13348
|
theme,
|
|
13323
13349
|
clientJsPath,
|
|
13324
13350
|
clientCssPath,
|
|
13325
|
-
nonce
|
|
13351
|
+
nonce,
|
|
13352
|
+
faviconPath: faviconInfo?.path || null,
|
|
13353
|
+
faviconType: faviconInfo?.type || null
|
|
13326
13354
|
});
|
|
13327
13355
|
let didError = false;
|
|
13328
13356
|
const { pipe, abort } = renderToPipeableStream(documentTree, {
|
|
@@ -13366,11 +13394,12 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
13366
13394
|
}
|
|
13367
13395
|
|
|
13368
13396
|
// modules/build/ssg/renderer.ts
|
|
13369
|
-
async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params) {
|
|
13397
|
+
async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params, config) {
|
|
13370
13398
|
const routeChunks = loadChunksFromManifest(projectRoot);
|
|
13371
13399
|
const assetManifest = loadAssetManifest(projectRoot);
|
|
13372
13400
|
const clientJsPath = getClientJsPath(projectRoot);
|
|
13373
13401
|
const clientCssPath = getClientCssPath(projectRoot);
|
|
13402
|
+
const faviconInfo = config ? getFaviconInfo(projectRoot, config.directories.static, false) : null;
|
|
13374
13403
|
const chunkName = routeChunks[route.pattern];
|
|
13375
13404
|
let chunkHref = null;
|
|
13376
13405
|
if (chunkName != null) {
|
|
@@ -13478,8 +13507,10 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params)
|
|
|
13478
13507
|
entrypointFiles,
|
|
13479
13508
|
clientJsPath,
|
|
13480
13509
|
clientCssPath,
|
|
13481
|
-
includeInlineScripts: true
|
|
13510
|
+
includeInlineScripts: true,
|
|
13482
13511
|
// SSG needs inline scripts (renderToString doesn't support bootstrapScripts)
|
|
13512
|
+
faviconPath: faviconInfo?.path || null,
|
|
13513
|
+
faviconType: faviconInfo?.type || null
|
|
13483
13514
|
});
|
|
13484
13515
|
const html = "<!DOCTYPE html>" + renderToString(documentTree);
|
|
13485
13516
|
const dir = pathToOutDir(ssgOutDir, urlPath);
|
|
@@ -13492,7 +13523,7 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params)
|
|
|
13492
13523
|
|
|
13493
13524
|
// modules/build/ssg/builder.ts
|
|
13494
13525
|
init_globals();
|
|
13495
|
-
async function buildStaticPages(projectRoot, routes) {
|
|
13526
|
+
async function buildStaticPages(projectRoot, routes, config) {
|
|
13496
13527
|
const ssgOutDir = path19.join(projectRoot, BUILD_FOLDER_NAME, "ssg");
|
|
13497
13528
|
ensureDir(ssgOutDir);
|
|
13498
13529
|
for (const route of routes) {
|
|
@@ -13541,7 +13572,7 @@ async function buildStaticPages(projectRoot, routes) {
|
|
|
13541
13572
|
}
|
|
13542
13573
|
for (const params of allParams) {
|
|
13543
13574
|
const urlPath = buildPathFromPattern(route.pattern, params);
|
|
13544
|
-
await renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params);
|
|
13575
|
+
await renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params, config);
|
|
13545
13576
|
}
|
|
13546
13577
|
}
|
|
13547
13578
|
console.log(`\u2705 [framework][ssg] Finished building all static pages`);
|
|
@@ -14190,7 +14221,7 @@ async function buildApp(options = {}) {
|
|
|
14190
14221
|
writeClientBoostrapManifest(projectRoot);
|
|
14191
14222
|
writeClientRoutesManifest(routes, projectRoot);
|
|
14192
14223
|
await buildClientBundle(projectRoot);
|
|
14193
|
-
await buildStaticPages(projectRoot, routes);
|
|
14224
|
+
await buildStaticPages(projectRoot, routes, config);
|
|
14194
14225
|
delete process.env.LOLY_BUILD;
|
|
14195
14226
|
console.log(`[framework][build] Build completed successfully`);
|
|
14196
14227
|
}
|
|
@@ -16432,7 +16463,8 @@ function setupRoutes(options) {
|
|
|
16432
16463
|
env: isDev ? "dev" : "prod",
|
|
16433
16464
|
ssgOutDir,
|
|
16434
16465
|
theme: req.cookies?.theme || "light",
|
|
16435
|
-
projectRoot
|
|
16466
|
+
projectRoot,
|
|
16467
|
+
config
|
|
16436
16468
|
});
|
|
16437
16469
|
});
|
|
16438
16470
|
}
|