@lolyjs/core 0.2.0-alpha.1 → 0.2.0-alpha.11

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.js CHANGED
@@ -42,17 +42,19 @@ __export(globals_exports, {
42
42
  NOT_FOUND_FILE_PREFIX: () => NOT_FOUND_FILE_PREFIX,
43
43
  NOT_FOUND_PATTERN: () => NOT_FOUND_PATTERN,
44
44
  PAGE_FILE_NAME: () => PAGE_FILE_NAME,
45
+ ROUTER_DATA_KEY: () => ROUTER_DATA_KEY,
45
46
  STATIC_PATH: () => STATIC_PATH,
46
47
  STYLE_FILE_NAME: () => STYLE_FILE_NAME,
47
48
  WINDOW_DATA_KEY: () => WINDOW_DATA_KEY
48
49
  });
49
- var BUILD_FOLDER_NAME, STYLE_FILE_NAME, WINDOW_DATA_KEY, APP_CONTAINER_ID, STATIC_PATH, NOT_FOUND_PATTERN, ERROR_PATTERN, NOT_FOUND_CHUNK_KEY, ERROR_CHUNK_KEY, NOT_FOUND_FILE_PREFIX, ERROR_FILE_PREFIX, PAGE_FILE_NAME, LAYOUT_FILE_NAME, FAVICON_PATH, CLIENT_CSS_PATH, CLIENT_JS_PATH, ASSETS_BASE_DIR;
50
+ var BUILD_FOLDER_NAME, STYLE_FILE_NAME, WINDOW_DATA_KEY, ROUTER_DATA_KEY, APP_CONTAINER_ID, STATIC_PATH, NOT_FOUND_PATTERN, ERROR_PATTERN, NOT_FOUND_CHUNK_KEY, ERROR_CHUNK_KEY, NOT_FOUND_FILE_PREFIX, ERROR_FILE_PREFIX, PAGE_FILE_NAME, LAYOUT_FILE_NAME, FAVICON_PATH, CLIENT_CSS_PATH, CLIENT_JS_PATH, ASSETS_BASE_DIR;
50
51
  var init_globals = __esm({
51
52
  "constants/globals.ts"() {
52
53
  "use strict";
53
54
  BUILD_FOLDER_NAME = ".loly";
54
55
  STYLE_FILE_NAME = "styles.css";
55
56
  WINDOW_DATA_KEY = "__FW_DATA__";
57
+ ROUTER_DATA_KEY = "__LOLY_ROUTER_DATA__";
56
58
  APP_CONTAINER_ID = "__app";
57
59
  STATIC_PATH = "/static";
58
60
  NOT_FOUND_PATTERN = "/not-found";
@@ -1485,6 +1487,7 @@ function createDocumentTree(options) {
1485
1487
  const {
1486
1488
  appTree,
1487
1489
  initialData,
1490
+ routerData,
1488
1491
  meta,
1489
1492
  titleFallback,
1490
1493
  descriptionFallback,
@@ -1522,6 +1525,9 @@ function createDocumentTree(options) {
1522
1525
  ...initialData,
1523
1526
  theme
1524
1527
  });
1528
+ const routerSerialized = JSON.stringify({
1529
+ ...routerData
1530
+ });
1525
1531
  const documentTree = React.createElement(
1526
1532
  "html",
1527
1533
  { lang },
@@ -1569,6 +1575,12 @@ function createDocumentTree(options) {
1569
1575
  dangerouslySetInnerHTML: {
1570
1576
  __html: `window.${WINDOW_DATA_KEY} = ${serialized};`
1571
1577
  }
1578
+ }),
1579
+ React.createElement("script", {
1580
+ nonce,
1581
+ dangerouslySetInnerHTML: {
1582
+ __html: `window.${ROUTER_DATA_KEY} = ${routerSerialized};`
1583
+ }
1572
1584
  })
1573
1585
  );
1574
1586
  return documentTree;
@@ -1591,6 +1603,15 @@ function buildInitialData(urlPath, params, loaderResult) {
1591
1603
  };
1592
1604
  }
1593
1605
 
1606
+ // modules/rendering/routerData/index.ts
1607
+ var buildRouterData = (req) => {
1608
+ return {
1609
+ pathname: req.path,
1610
+ params: req.params,
1611
+ searchParams: req.query
1612
+ };
1613
+ };
1614
+
1594
1615
  // modules/build/ssg/renderer.ts
1595
1616
  init_globals();
1596
1617
  async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params) {
@@ -1644,10 +1665,12 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params)
1644
1665
  return;
1645
1666
  }
1646
1667
  const initialData = buildInitialData(urlPath, params, loaderResult);
1668
+ const routerData = buildRouterData(req);
1647
1669
  const appTree = buildAppTree(route, params, initialData.props);
1648
1670
  const documentTree = createDocumentTree({
1649
1671
  appTree,
1650
1672
  initialData,
1673
+ routerData,
1651
1674
  meta: loaderResult.metadata,
1652
1675
  titleFallback: "My Framework Dev",
1653
1676
  descriptionFallback: "Static page generated by @lolyjs/core.",
@@ -4449,6 +4472,7 @@ async function handlePageRequestInternal(options) {
4449
4472
  }
4450
4473
  }
4451
4474
  const matched = matchRoute(routes, urlPath);
4475
+ const routerData = buildRouterData(req);
4452
4476
  if (!matched) {
4453
4477
  if (notFoundPage) {
4454
4478
  const ctx2 = {
@@ -4469,6 +4493,7 @@ async function handlePageRequestInternal(options) {
4469
4493
  const documentTree2 = createDocumentTree({
4470
4494
  appTree: appTree2,
4471
4495
  initialData: initialData2,
4496
+ routerData,
4472
4497
  meta: loaderResult2.metadata ?? null,
4473
4498
  titleFallback: "Not found",
4474
4499
  descriptionFallback: "Loly demo",
@@ -4576,6 +4601,7 @@ async function handlePageRequestInternal(options) {
4576
4601
  const documentTree = createDocumentTree({
4577
4602
  appTree,
4578
4603
  initialData,
4604
+ routerData,
4579
4605
  meta: loaderResult.metadata,
4580
4606
  titleFallback: "Loly framework",
4581
4607
  descriptionFallback: "Loly demo",
@@ -4633,6 +4659,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
4633
4659
  loaderResult.theme = theme;
4634
4660
  }
4635
4661
  const initialData = buildInitialData(req.path, { error: String(error) }, loaderResult);
4662
+ const routerData = buildRouterData(req);
4636
4663
  initialData.error = true;
4637
4664
  if (isDataReq) {
4638
4665
  res.statusCode = 500;
@@ -4663,6 +4690,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
4663
4690
  const documentTree = createDocumentTree({
4664
4691
  appTree,
4665
4692
  initialData,
4693
+ routerData,
4666
4694
  meta: loaderResult.metadata ?? null,
4667
4695
  titleFallback: "Error",
4668
4696
  descriptionFallback: "An error occurred",
@@ -4867,7 +4895,11 @@ var setupApplication = async ({
4867
4895
  helmetConfig.contentSecurityPolicy = {
4868
4896
  directives: {
4869
4897
  defaultSrc: ["'self'"],
4870
- styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
4898
+ styleSrc: [
4899
+ "'self'",
4900
+ "'unsafe-inline'",
4901
+ "https://fonts.googleapis.com"
4902
+ ],
4871
4903
  scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
4872
4904
  imgSrc: ["'self'", "data:", "https:"],
4873
4905
  // Allow fetch/XHR to any HTTPS endpoint - users can restrict in their config if needed
@@ -4884,7 +4916,11 @@ var setupApplication = async ({
4884
4916
  const defaultCSP = {
4885
4917
  directives: {
4886
4918
  defaultSrc: ["'self'"],
4887
- styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
4919
+ styleSrc: [
4920
+ "'self'",
4921
+ "'unsafe-inline'",
4922
+ "https://fonts.googleapis.com"
4923
+ ],
4888
4924
  scriptSrc: ["'self'", nonceFunction],
4889
4925
  imgSrc: ["'self'", "data:", "https:"],
4890
4926
  // Allow fetch/XHR to any HTTPS endpoint - users can restrict in their config if needed
@@ -4907,10 +4943,7 @@ var setupApplication = async ({
4907
4943
  (src) => typeof src === "function"
4908
4944
  );
4909
4945
  if (!hasNonceSupport) {
4910
- mergedDirectives.scriptSrc = [
4911
- ...userScriptSrc,
4912
- nonceFunction
4913
- ];
4946
+ mergedDirectives.scriptSrc = [...userScriptSrc, nonceFunction];
4914
4947
  } else {
4915
4948
  mergedDirectives.scriptSrc = userScriptSrc;
4916
4949
  }
@@ -4918,19 +4951,25 @@ var setupApplication = async ({
4918
4951
  const userConnectSrc = userDirectives.connectSrc;
4919
4952
  if (userConnectSrc && Array.isArray(userConnectSrc)) {
4920
4953
  const defaultConnectSrc = defaultCSP.directives.connectSrc || [];
4921
- const mergedConnectSrc = [.../* @__PURE__ */ new Set([...defaultConnectSrc, ...userConnectSrc])];
4954
+ const mergedConnectSrc = [
4955
+ .../* @__PURE__ */ new Set([...defaultConnectSrc, ...userConnectSrc])
4956
+ ];
4922
4957
  mergedDirectives.connectSrc = mergedConnectSrc;
4923
4958
  }
4924
4959
  const userStyleSrc = userDirectives.styleSrc;
4925
4960
  if (userStyleSrc && Array.isArray(userStyleSrc)) {
4926
4961
  const defaultStyleSrc = defaultCSP.directives.styleSrc || [];
4927
- const mergedStyleSrc = [.../* @__PURE__ */ new Set([...defaultStyleSrc, ...userStyleSrc])];
4962
+ const mergedStyleSrc = [
4963
+ .../* @__PURE__ */ new Set([...defaultStyleSrc, ...userStyleSrc])
4964
+ ];
4928
4965
  mergedDirectives.styleSrc = mergedStyleSrc;
4929
4966
  }
4930
4967
  const userFontSrc = userDirectives.fontSrc;
4931
4968
  if (userFontSrc && Array.isArray(userFontSrc)) {
4932
4969
  const defaultFontSrc = defaultCSP.directives.fontSrc || [];
4933
- const mergedFontSrc = [.../* @__PURE__ */ new Set([...defaultFontSrc, ...userFontSrc])];
4970
+ const mergedFontSrc = [
4971
+ .../* @__PURE__ */ new Set([...defaultFontSrc, ...userFontSrc])
4972
+ ];
4934
4973
  mergedDirectives.fontSrc = mergedFontSrc;
4935
4974
  }
4936
4975
  helmetConfig.contentSecurityPolicy = {
@@ -4950,23 +4989,27 @@ var setupApplication = async ({
4950
4989
  helmetConfig.hsts = false;
4951
4990
  }
4952
4991
  if (process.env.NODE_ENV !== "development" && security?.contentSecurityPolicy !== false) {
4953
- app.use((req, res, next) => {
4954
- const nonce = crypto.randomBytes(16).toString("base64");
4955
- res.locals.nonce = nonce;
4956
- next();
4957
- });
4992
+ app.use(
4993
+ (req, res, next) => {
4994
+ const nonce = crypto.randomBytes(16).toString("base64");
4995
+ res.locals.nonce = nonce;
4996
+ next();
4997
+ }
4998
+ );
4958
4999
  }
4959
5000
  app.use(helmet(helmetConfig));
4960
5001
  const appLogger = createModuleLogger("framework");
4961
- app.use(requestLoggerMiddleware({
4962
- logger: appLogger.child({ component: "server" }),
4963
- logRequests: process.env.LOG_REQUESTS === "true",
4964
- // Default to false (only errors/warnings)
4965
- logResponses: process.env.LOG_RESPONSES !== "false",
4966
- // Default to true (but filtered)
4967
- logStaticAssets: process.env.LOG_STATIC_ASSETS === "true"
4968
- // Default to false
4969
- }));
5002
+ app.use(
5003
+ requestLoggerMiddleware({
5004
+ logger: appLogger.child({ component: "server" }),
5005
+ logRequests: process.env.LOG_REQUESTS === "true",
5006
+ // Default to false (only errors/warnings)
5007
+ logResponses: process.env.LOG_RESPONSES !== "false",
5008
+ // Default to true (but filtered)
5009
+ logStaticAssets: process.env.LOG_STATIC_ASSETS === "true"
5010
+ // Default to false
5011
+ })
5012
+ );
4970
5013
  const corsOptions = {
4971
5014
  credentials: true
4972
5015
  };
@@ -4982,7 +5025,7 @@ var setupApplication = async ({
4982
5025
  corsOptions.origin = process.env.NODE_ENV === "development";
4983
5026
  }
4984
5027
  app.use(cors(corsOptions));
4985
- if (rateLimit2) {
5028
+ if (rateLimit2 && process.env.NODE_ENV !== "development") {
4986
5029
  const generalLimiter = createRateLimiter({
4987
5030
  windowMs: rateLimit2.windowMs,
4988
5031
  max: rateLimit2.max
@@ -5088,7 +5131,7 @@ async function startProdServer(options = {}) {
5088
5131
  import { hydrateRoot } from "react-dom/client";
5089
5132
 
5090
5133
  // modules/runtime/client/AppShell.tsx
5091
- import { useEffect, useState, useRef } from "react";
5134
+ import { useEffect, useState, useRef, useCallback } from "react";
5092
5135
 
5093
5136
  // modules/runtime/client/RouterView.tsx
5094
5137
  import { jsx } from "react/jsx-runtime";
@@ -5117,6 +5160,10 @@ var dataCache = cacheStore.data;
5117
5160
  var pathIndex = cacheStore.index;
5118
5161
  var lru = cacheStore.lru;
5119
5162
 
5163
+ // modules/runtime/client/RouterContext.tsx
5164
+ import { createContext, useContext } from "react";
5165
+ var RouterContext = createContext(null);
5166
+
5120
5167
  // modules/runtime/client/AppShell.tsx
5121
5168
  import { jsx as jsx2 } from "react/jsx-runtime";
5122
5169