@modern-js/server-core 2.47.1-alpha.1 → 2.47.1-alpha.3

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.
Files changed (33) hide show
  1. package/dist/cjs/base/adapters/node/bff.js +1 -1
  2. package/dist/cjs/base/adapters/node/middlewares/templates.js +3 -31
  3. package/dist/cjs/base/adapters/node/node.js +5 -0
  4. package/dist/cjs/base/index.js +0 -4
  5. package/dist/cjs/base/middlewares/customServer/index.js +5 -1
  6. package/dist/cjs/base/middlewares/index.js +0 -2
  7. package/dist/cjs/base/middlewares/{dataHandler.js → renderHandler/dataHandler.js} +21 -30
  8. package/dist/cjs/base/middlewares/renderHandler/index.js +3 -3
  9. package/dist/cjs/base/middlewares/renderHandler/render.js +23 -4
  10. package/dist/cjs/base/middlewares/renderHandler/ssrRender.js +1 -1
  11. package/dist/cjs/base/utils/templates.js +47 -0
  12. package/dist/esm/base/adapters/node/bff.js +1 -1
  13. package/dist/esm/base/adapters/node/middlewares/templates.js +2 -20
  14. package/dist/esm/base/adapters/node/node.js +6 -1
  15. package/dist/esm/base/index.js +2 -4
  16. package/dist/esm/base/middlewares/customServer/index.js +5 -1
  17. package/dist/esm/base/middlewares/index.js +0 -1
  18. package/dist/esm/base/middlewares/renderHandler/dataHandler.js +26 -0
  19. package/dist/esm/base/middlewares/renderHandler/index.js +3 -3
  20. package/dist/esm/base/middlewares/renderHandler/render.js +23 -4
  21. package/dist/esm/base/middlewares/renderHandler/ssrRender.js +1 -1
  22. package/dist/esm/base/utils/templates.js +23 -0
  23. package/dist/types/base/index.d.ts +2 -2
  24. package/dist/types/base/middlewares/index.d.ts +0 -1
  25. package/dist/types/base/middlewares/renderHandler/dataHandler.d.ts +5 -0
  26. package/dist/types/base/middlewares/renderHandler/index.d.ts +1 -1
  27. package/dist/types/base/middlewares/renderHandler/render.d.ts +1 -1
  28. package/dist/types/base/middlewares/renderHandler/ssrRender.d.ts +1 -3
  29. package/dist/types/base/utils/templates.d.ts +2 -0
  30. package/dist/types/index.d.ts +1 -0
  31. package/package.json +4 -4
  32. package/dist/esm/base/middlewares/dataHandler.js +0 -35
  33. package/dist/types/base/middlewares/dataHandler.d.ts +0 -3
@@ -37,13 +37,13 @@ const bindBFFHandler = async (server, options) => {
37
37
  await runner.gather(collector);
38
38
  const webOnly = await (0, import_utils.isWebOnly)();
39
39
  let handler;
40
- const renderHandler = (0, import_middlewares.getRenderHandler)(options);
41
40
  if (webOnly) {
42
41
  handler = async (c, next) => {
43
42
  c.body("");
44
43
  await next();
45
44
  };
46
45
  } else {
46
+ const renderHandler = enableHandleWeb ? await (0, import_middlewares.getRenderHandler)(options) : null;
47
47
  handler = await server.runner.prepareApiServer({
48
48
  pwd: options.pwd,
49
49
  prefix,
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,43 +15,17 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var templates_exports = {};
30
20
  __export(templates_exports, {
31
21
  createInjectHtml: () => createInjectHtml
32
22
  });
33
23
  module.exports = __toCommonJS(templates_exports);
34
- var import_path = __toESM(require("path"));
35
- var import_fileReader = require("@modern-js/runtime-utils/fileReader");
36
- async function getHtmlTemplates(pwd, routes) {
37
- const htmls = await Promise.all(routes.map(async (route) => {
38
- let html;
39
- try {
40
- var _this;
41
- const htmlPath = import_path.default.join(pwd, route.entryPath);
42
- html = (_this = await import_fileReader.fileReader.readFile(htmlPath, "utf-8")) === null || _this === void 0 ? void 0 : _this.toString();
43
- } catch (e) {
44
- }
45
- return [
46
- route.entryName,
47
- html
48
- ];
49
- }) || []);
50
- const templates = Object.fromEntries(htmls);
51
- return templates;
52
- }
24
+ var import_templates = require("../../../utils/templates");
53
25
  function createInjectHtml(pwd, routes) {
54
26
  return async (c, next) => {
55
- if (c.req.method.toUpperCase() === "GET" && !c.get("templates") && routes) {
56
- const templates = await getHtmlTemplates(pwd, routes);
27
+ if (!c.get("templates") && routes) {
28
+ const templates = await (0, import_templates.getHtmlTemplates)(pwd, routes);
57
29
  c.set("templates", templates);
58
30
  }
59
31
  return next();
@@ -28,6 +28,7 @@ var import_stream = require("./polyfills/stream");
28
28
  var import_install = require("./polyfills/install");
29
29
  (0, import_install.installGlobals)();
30
30
  const createWebRequest = (req, res) => {
31
+ var _req_url;
31
32
  const headerRecord = [];
32
33
  const len = req.rawHeaders.length;
33
34
  for (let i = 0; i < len; i += 2) {
@@ -44,6 +45,10 @@ const createWebRequest = (req, res) => {
44
45
  signal: controller.signal
45
46
  };
46
47
  res.on("close", () => controller.abort());
48
+ if (!(method === "GET" || method === "HEAD") && ((_req_url = req.url) === null || _req_url === void 0 ? void 0 : _req_url.includes("__loader"))) {
49
+ init.body = (0, import_stream.createReadableStreamFromReadable)(req);
50
+ init.duplex = "half";
51
+ }
47
52
  const url = `http://${req.headers.host}${req.url}`;
48
53
  const request = new Request(url, init);
49
54
  return request;
@@ -20,7 +20,6 @@ var base_exports = {};
20
20
  __export(base_exports, {
21
21
  AGGRED_DIR: () => import_constants.AGGRED_DIR,
22
22
  bindBFFHandler: () => import_node.bindBFFHandler,
23
- bindDataHandlers: () => import_middlewares.bindDataHandlers,
24
23
  bindRenderHandler: () => import_middlewares.bindRenderHandler,
25
24
  connectMid2HonoMid: () => import_node.connectMid2HonoMid,
26
25
  createErrorHtml: () => import_utils.createErrorHtml,
@@ -28,7 +27,6 @@ __export(base_exports, {
28
27
  createNodeServer: () => import_node.createNodeServer,
29
28
  createServerBase: () => createServerBase,
30
29
  createStaticMiddleware: () => import_node.createStaticMiddleware,
31
- createWebRequest: () => import_node.createWebRequest,
32
30
  favionFallbackMiddleware: () => import_middlewares.favionFallbackMiddleware,
33
31
  getRenderHandler: () => import_middlewares.getRenderHandler,
34
32
  httpCallBack2HonoMid: () => import_node.httpCallBack2HonoMid,
@@ -55,7 +53,6 @@ function createServerBase(options) {
55
53
  0 && (module.exports = {
56
54
  AGGRED_DIR,
57
55
  bindBFFHandler,
58
- bindDataHandlers,
59
56
  bindRenderHandler,
60
57
  connectMid2HonoMid,
61
58
  createErrorHtml,
@@ -63,7 +60,6 @@ function createServerBase(options) {
63
60
  createNodeServer,
64
61
  createServerBase,
65
62
  createStaticMiddleware,
66
- createWebRequest,
67
63
  favionFallbackMiddleware,
68
64
  getRenderHandler,
69
65
  httpCallBack2HonoMid,
@@ -28,6 +28,10 @@ var import_constants = require("../../constants");
28
28
  var import_context = require("./context");
29
29
  const noop = () => {
30
30
  };
31
+ const isHtmlResponse = (response) => {
32
+ const contentType = response.headers.get("content-type");
33
+ return contentType === null || contentType === void 0 ? void 0 : contentType.includes("text/html");
34
+ };
31
35
  class CustomServer {
32
36
  getHookMiddleware(entryName, routes) {
33
37
  return async (c, next) => {
@@ -61,7 +65,7 @@ class CustomServer {
61
65
  return void 0;
62
66
  }
63
67
  await next();
64
- if (c.finalized && !c.res.body) {
68
+ if (c.finalized && (!c.res.body || !isHtmlResponse(c.res))) {
65
69
  return void 0;
66
70
  }
67
71
  if (routeInfo.isStream) {
@@ -16,13 +16,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
16
16
  var middlewares_exports = {};
17
17
  module.exports = __toCommonJS(middlewares_exports);
18
18
  __reExport(middlewares_exports, require("./faviconFallback"), module.exports);
19
- __reExport(middlewares_exports, require("./dataHandler"), module.exports);
20
19
  __reExport(middlewares_exports, require("./monitor"), module.exports);
21
20
  __reExport(middlewares_exports, require("./renderHandler"), module.exports);
22
21
  // Annotate the CommonJS export names for ESM import in node:
23
22
  0 && (module.exports = {
24
23
  ...require("./faviconFallback"),
25
- ...require("./dataHandler"),
26
24
  ...require("./monitor"),
27
25
  ...require("./renderHandler")
28
26
  });
@@ -28,42 +28,33 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var dataHandler_exports = {};
30
30
  __export(dataHandler_exports, {
31
- bindDataHandlers: () => bindDataHandlers
31
+ dataHandler: () => dataHandler
32
32
  });
33
33
  module.exports = __toCommonJS(dataHandler_exports);
34
34
  var import_utils = require("@modern-js/utils");
35
- var import_utils2 = require("../utils");
36
- const bindDataHandlers = async (server, routes, distDir) => {
35
+ var import_utils2 = require("../../utils");
36
+ const dataHandler = async (request, { routeInfo, serverRoutes, pwd, reporter, logger }) => {
37
37
  const path = await (0, import_utils2.getPathModule)();
38
- routes.sort(import_utils2.sortRoutes).forEach((route) => {
39
- const bundlePath = path.join(distDir, import_utils.SERVER_BUNDLE_DIRECTORY, `${route.entryName || import_utils.MAIN_ENTRY_NAME}-server-loaders.js`);
40
- server.all(`${route.urlPath === "/" ? "*" : `${route.urlPath}/*`}`, createDataHandler(routes, bundlePath));
38
+ const serverLoaderBundlePath = path.join(pwd, import_utils.SERVER_BUNDLE_DIRECTORY, `${routeInfo.entryName || import_utils.MAIN_ENTRY_NAME}-server-loaders.js`);
39
+ let serverLoaderModule;
40
+ try {
41
+ serverLoaderModule = await Promise.resolve().then(() => __toESM(require(serverLoaderBundlePath)));
42
+ } catch (_) {
43
+ return;
44
+ }
45
+ const { routes, handleRequest } = serverLoaderModule;
46
+ const response = await handleRequest({
47
+ request,
48
+ serverRoutes,
49
+ context: {
50
+ logger,
51
+ reporter
52
+ },
53
+ routes
41
54
  });
42
- };
43
- const createDataHandler = (serverRoutes, buildModulePath) => {
44
- return async (context, next) => {
45
- let buildModule;
46
- try {
47
- buildModule = await Promise.resolve().then(() => __toESM(require(buildModulePath)));
48
- } catch (_) {
49
- return next();
50
- }
51
- const { routes, handleRequest } = buildModule;
52
- const logger = context.get("logger");
53
- const reporter = context.get("reporter");
54
- const response = await handleRequest({
55
- request: context.req.raw,
56
- serverRoutes,
57
- context: {
58
- logger,
59
- reporter
60
- },
61
- routes
62
- });
63
- return response ? response : next();
64
- };
55
+ return response;
65
56
  };
66
57
  // Annotate the CommonJS export names for ESM import in node:
67
58
  0 && (module.exports = {
68
- bindDataHandlers
59
+ dataHandler
69
60
  });
@@ -44,7 +44,7 @@ function createRenderHandler(render) {
44
44
  return res;
45
45
  };
46
46
  }
47
- function getRenderHandler(options) {
47
+ async function getRenderHandler(options) {
48
48
  const { routes, pwd, config } = options;
49
49
  if (routes && routes.length > 0) {
50
50
  var _config_server, _options_config_security;
@@ -81,8 +81,8 @@ async function bindRenderHandler(server, options) {
81
81
  const customServerMiddleware = customServer.getServerMiddleware();
82
82
  server.use(urlPath, customServerMiddleware);
83
83
  }
84
- const render = getRenderHandler(options);
85
- render && server.get("*", createRenderHandler(render));
84
+ const render = await getRenderHandler(options);
85
+ render && server.all("*", createRenderHandler(render));
86
86
  }
87
87
  }
88
88
  // Annotate the CommonJS export names for ESM import in node:
@@ -24,8 +24,9 @@ module.exports = __toCommonJS(render_exports);
24
24
  var import_utils = require("@modern-js/utils");
25
25
  var import_request = require("../../utils/request");
26
26
  var import_utils2 = require("../../utils");
27
+ var import_dataHandler = require("./dataHandler");
27
28
  var import_ssrRender = require("./ssrRender");
28
- function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce }) {
29
+ async function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce }) {
29
30
  return async (req, { logger, nodeReq, reporter, tpls }) => {
30
31
  const routeInfo = matchRoute(req, routes);
31
32
  if (!routeInfo) {
@@ -41,7 +42,7 @@ function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce }
41
42
  throw new Error(`Can't found entry ${routeInfo.entryName} html `);
42
43
  }
43
44
  const renderMode = getRenderMode(req, metaName || "modern-js", routeInfo.isSSR, forceCSR);
44
- return renderMode === "csr" ? csrRender(html) : (0, import_ssrRender.ssrRender)(req, {
45
+ const renderOptions = {
45
46
  pwd,
46
47
  mode: "string",
47
48
  html,
@@ -51,8 +52,23 @@ function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce }
51
52
  nonce,
52
53
  logger,
53
54
  nodeReq,
54
- reporter
55
- });
55
+ reporter,
56
+ serverRoutes: routes
57
+ };
58
+ switch (renderMode) {
59
+ case "data":
60
+ let response = await (0, import_dataHandler.dataHandler)(req, renderOptions);
61
+ if (!response) {
62
+ response = await (0, import_ssrRender.ssrRender)(req, renderOptions);
63
+ }
64
+ return response;
65
+ case "ssr":
66
+ return (0, import_ssrRender.ssrRender)(req, renderOptions);
67
+ case "csr":
68
+ return csrRender(html);
69
+ default:
70
+ throw new Error(`Unknown render mode: ${renderMode}`);
71
+ }
56
72
  };
57
73
  }
58
74
  function matchRoute(req, routes) {
@@ -68,6 +84,9 @@ function matchRoute(req, routes) {
68
84
  function getRenderMode(req, framework, isSSR, forceCSR) {
69
85
  const query = (0, import_request.parseQuery)(req);
70
86
  if (isSSR) {
87
+ if (query.__loader) {
88
+ return "data";
89
+ }
71
90
  if (forceCSR && (query.csr || req.headers.get(`x-${(0, import_utils.cutNameByHyphen)(framework)}-ssr-fallback`))) {
72
91
  return "csr";
73
92
  }
@@ -103,7 +103,7 @@ async function ssrRender(request, { routeInfo, pwd, html, staticGenerate, nonce,
103
103
  serverTiming: new import_serverTiming.ServerTiming(responseProxy.headers, metaName),
104
104
  reporter: reporter || defaultReporter,
105
105
  /** @deprecated node req */
106
- req: void 0,
106
+ req: nodeReq,
107
107
  /** @deprecated node res */
108
108
  res: void 0,
109
109
  isSpider,
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var templates_exports = {};
20
+ __export(templates_exports, {
21
+ getHtmlTemplates: () => getHtmlTemplates
22
+ });
23
+ module.exports = __toCommonJS(templates_exports);
24
+ var import_fileReader = require("@modern-js/runtime-utils/fileReader");
25
+ var import_path = require("./path");
26
+ async function getHtmlTemplates(pwd, routes) {
27
+ const path = await (0, import_path.getPathModule)();
28
+ const htmls = await Promise.all(routes.map(async (route) => {
29
+ let html;
30
+ try {
31
+ var _this;
32
+ const htmlPath = path.join(pwd, route.entryPath);
33
+ html = (_this = await import_fileReader.fileReader.readFile(htmlPath, "utf-8")) === null || _this === void 0 ? void 0 : _this.toString();
34
+ } catch (e) {
35
+ }
36
+ return [
37
+ route.entryName,
38
+ html
39
+ ];
40
+ }) || []);
41
+ const templates = Object.fromEntries(htmls);
42
+ return templates;
43
+ }
44
+ // Annotate the CommonJS export names for ESM import in node:
45
+ 0 && (module.exports = {
46
+ getHtmlTemplates
47
+ });
@@ -14,13 +14,13 @@ const bindBFFHandler = async (server, options) => {
14
14
  await runner.gather(collector);
15
15
  const webOnly = await isWebOnly();
16
16
  let handler;
17
- const renderHandler = getRenderHandler(options);
18
17
  if (webOnly) {
19
18
  handler = async (c, next) => {
20
19
  c.body("");
21
20
  await next();
22
21
  };
23
22
  } else {
23
+ const renderHandler = enableHandleWeb ? await getRenderHandler(options) : null;
24
24
  handler = await server.runner.prepareApiServer({
25
25
  pwd: options.pwd,
26
26
  prefix,
@@ -1,25 +1,7 @@
1
- import path from "path";
2
- import { fileReader } from "@modern-js/runtime-utils/fileReader";
3
- async function getHtmlTemplates(pwd, routes) {
4
- const htmls = await Promise.all(routes.map(async (route) => {
5
- let html;
6
- try {
7
- var _this;
8
- const htmlPath = path.join(pwd, route.entryPath);
9
- html = (_this = await fileReader.readFile(htmlPath, "utf-8")) === null || _this === void 0 ? void 0 : _this.toString();
10
- } catch (e) {
11
- }
12
- return [
13
- route.entryName,
14
- html
15
- ];
16
- }) || []);
17
- const templates = Object.fromEntries(htmls);
18
- return templates;
19
- }
1
+ import { getHtmlTemplates } from "../../../utils/templates";
20
2
  function createInjectHtml(pwd, routes) {
21
3
  return async (c, next) => {
22
- if (c.req.method.toUpperCase() === "GET" && !c.get("templates") && routes) {
4
+ if (!c.get("templates") && routes) {
23
5
  const templates = await getHtmlTemplates(pwd, routes);
24
6
  c.set("templates", templates);
25
7
  }
@@ -1,8 +1,9 @@
1
1
  import { createServer, ServerResponse } from "node:http";
2
- import { writeReadableStreamToWritable } from "./polyfills/stream";
2
+ import { createReadableStreamFromReadable, writeReadableStreamToWritable } from "./polyfills/stream";
3
3
  import { installGlobals } from "./polyfills/install";
4
4
  installGlobals();
5
5
  const createWebRequest = (req, res) => {
6
+ var _req_url;
6
7
  const headerRecord = [];
7
8
  const len = req.rawHeaders.length;
8
9
  for (let i = 0; i < len; i += 2) {
@@ -19,6 +20,10 @@ const createWebRequest = (req, res) => {
19
20
  signal: controller.signal
20
21
  };
21
22
  res.on("close", () => controller.abort());
23
+ if (!(method === "GET" || method === "HEAD") && ((_req_url = req.url) === null || _req_url === void 0 ? void 0 : _req_url.includes("__loader"))) {
24
+ init.body = createReadableStreamFromReadable(req);
25
+ init.duplex = "half";
26
+ }
22
27
  const url = `http://${req.headers.host}${req.url}`;
23
28
  const request = new Request(url, init);
24
29
  return request;
@@ -1,8 +1,8 @@
1
1
  import { ServerBase } from "./serverBase";
2
2
  import { createErrorHtml } from "./utils";
3
3
  import { AGGRED_DIR } from "./constants";
4
- import { httpCallBack2HonoMid, createNodeServer, loadServerEnv, connectMid2HonoMid, sendResponse, createStaticMiddleware, bindBFFHandler, registerMockHandlers, createInjectHtml, createWebRequest } from "./adapters/node";
5
- import { favionFallbackMiddleware, bindDataHandlers, injectReporter, getRenderHandler, injectLogger, bindRenderHandler } from "./middlewares";
4
+ import { httpCallBack2HonoMid, createNodeServer, loadServerEnv, connectMid2HonoMid, sendResponse, createStaticMiddleware, bindBFFHandler, registerMockHandlers, createInjectHtml } from "./adapters/node";
5
+ import { favionFallbackMiddleware, injectReporter, getRenderHandler, injectLogger, bindRenderHandler } from "./middlewares";
6
6
  function createServerBase(options) {
7
7
  if (options == null) {
8
8
  throw new Error("can not start server without options");
@@ -13,7 +13,6 @@ function createServerBase(options) {
13
13
  export {
14
14
  AGGRED_DIR,
15
15
  bindBFFHandler,
16
- bindDataHandlers,
17
16
  bindRenderHandler,
18
17
  connectMid2HonoMid,
19
18
  createErrorHtml,
@@ -21,7 +20,6 @@ export {
21
20
  createNodeServer,
22
21
  createServerBase,
23
22
  createStaticMiddleware,
24
- createWebRequest,
25
23
  favionFallbackMiddleware,
26
24
  getRenderHandler,
27
25
  httpCallBack2HonoMid,
@@ -5,6 +5,10 @@ import { ServerReportTimings } from "../../constants";
5
5
  import { createAfterMatchCtx, createAfterRenderCtx, createCustomMiddlewaresCtx, createAfterStreamingRenderContext } from "./context";
6
6
  const noop = () => {
7
7
  };
8
+ const isHtmlResponse = (response) => {
9
+ const contentType = response.headers.get("content-type");
10
+ return contentType === null || contentType === void 0 ? void 0 : contentType.includes("text/html");
11
+ };
8
12
  class CustomServer {
9
13
  getHookMiddleware(entryName, routes) {
10
14
  return async (c, next) => {
@@ -38,7 +42,7 @@ class CustomServer {
38
42
  return void 0;
39
43
  }
40
44
  await next();
41
- if (c.finalized && !c.res.body) {
45
+ if (c.finalized && (!c.res.body || !isHtmlResponse(c.res))) {
42
46
  return void 0;
43
47
  }
44
48
  if (routeInfo.isStream) {
@@ -1,4 +1,3 @@
1
1
  export * from "./faviconFallback";
2
- export * from "./dataHandler";
3
2
  export * from "./monitor";
4
3
  export * from "./renderHandler";
@@ -0,0 +1,26 @@
1
+ import { MAIN_ENTRY_NAME, SERVER_BUNDLE_DIRECTORY } from "@modern-js/utils";
2
+ import { getPathModule } from "../../utils";
3
+ const dataHandler = async (request, { routeInfo, serverRoutes, pwd, reporter, logger }) => {
4
+ const path = await getPathModule();
5
+ const serverLoaderBundlePath = path.join(pwd, SERVER_BUNDLE_DIRECTORY, `${routeInfo.entryName || MAIN_ENTRY_NAME}-server-loaders.js`);
6
+ let serverLoaderModule;
7
+ try {
8
+ serverLoaderModule = await import(serverLoaderBundlePath);
9
+ } catch (_) {
10
+ return;
11
+ }
12
+ const { routes, handleRequest } = serverLoaderModule;
13
+ const response = await handleRequest({
14
+ request,
15
+ serverRoutes,
16
+ context: {
17
+ logger,
18
+ reporter
19
+ },
20
+ routes
21
+ });
22
+ return response;
23
+ };
24
+ export {
25
+ dataHandler
26
+ };
@@ -20,7 +20,7 @@ function createRenderHandler(render) {
20
20
  return res;
21
21
  };
22
22
  }
23
- function getRenderHandler(options) {
23
+ async function getRenderHandler(options) {
24
24
  const { routes, pwd, config } = options;
25
25
  if (routes && routes.length > 0) {
26
26
  var _config_server, _options_config_security;
@@ -57,8 +57,8 @@ async function bindRenderHandler(server, options) {
57
57
  const customServerMiddleware = customServer.getServerMiddleware();
58
58
  server.use(urlPath, customServerMiddleware);
59
59
  }
60
- const render = getRenderHandler(options);
61
- render && server.get("*", createRenderHandler(render));
60
+ const render = await getRenderHandler(options);
61
+ render && server.all("*", createRenderHandler(render));
62
62
  }
63
63
  }
64
64
  export {
@@ -1,8 +1,9 @@
1
1
  import { cutNameByHyphen } from "@modern-js/utils";
2
2
  import { parseQuery } from "../../utils/request";
3
3
  import { createErrorHtml, sortRoutes } from "../../utils";
4
+ import { dataHandler } from "./dataHandler";
4
5
  import { ssrRender } from "./ssrRender";
5
- function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce }) {
6
+ async function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce }) {
6
7
  return async (req, { logger, nodeReq, reporter, tpls }) => {
7
8
  const routeInfo = matchRoute(req, routes);
8
9
  if (!routeInfo) {
@@ -18,7 +19,7 @@ function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce }
18
19
  throw new Error(`Can't found entry ${routeInfo.entryName} html `);
19
20
  }
20
21
  const renderMode = getRenderMode(req, metaName || "modern-js", routeInfo.isSSR, forceCSR);
21
- return renderMode === "csr" ? csrRender(html) : ssrRender(req, {
22
+ const renderOptions = {
22
23
  pwd,
23
24
  mode: "string",
24
25
  html,
@@ -28,8 +29,23 @@ function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce }
28
29
  nonce,
29
30
  logger,
30
31
  nodeReq,
31
- reporter
32
- });
32
+ reporter,
33
+ serverRoutes: routes
34
+ };
35
+ switch (renderMode) {
36
+ case "data":
37
+ let response = await dataHandler(req, renderOptions);
38
+ if (!response) {
39
+ response = await ssrRender(req, renderOptions);
40
+ }
41
+ return response;
42
+ case "ssr":
43
+ return ssrRender(req, renderOptions);
44
+ case "csr":
45
+ return csrRender(html);
46
+ default:
47
+ throw new Error(`Unknown render mode: ${renderMode}`);
48
+ }
33
49
  };
34
50
  }
35
51
  function matchRoute(req, routes) {
@@ -45,6 +61,9 @@ function matchRoute(req, routes) {
45
61
  function getRenderMode(req, framework, isSSR, forceCSR) {
46
62
  const query = parseQuery(req);
47
63
  if (isSSR) {
64
+ if (query.__loader) {
65
+ return "data";
66
+ }
48
67
  if (forceCSR && (query.csr || req.headers.get(`x-${cutNameByHyphen(framework)}-ssr-fallback`))) {
49
68
  return "csr";
50
69
  }
@@ -70,7 +70,7 @@ async function ssrRender(request, { routeInfo, pwd, html, staticGenerate, nonce,
70
70
  serverTiming: new ServerTiming(responseProxy.headers, metaName),
71
71
  reporter: reporter || defaultReporter,
72
72
  /** @deprecated node req */
73
- req: void 0,
73
+ req: nodeReq,
74
74
  /** @deprecated node res */
75
75
  res: void 0,
76
76
  isSpider,
@@ -0,0 +1,23 @@
1
+ import { fileReader } from "@modern-js/runtime-utils/fileReader";
2
+ import { getPathModule } from "./path";
3
+ async function getHtmlTemplates(pwd, routes) {
4
+ const path = await getPathModule();
5
+ const htmls = await Promise.all(routes.map(async (route) => {
6
+ let html;
7
+ try {
8
+ var _this;
9
+ const htmlPath = path.join(pwd, route.entryPath);
10
+ html = (_this = await fileReader.readFile(htmlPath, "utf-8")) === null || _this === void 0 ? void 0 : _this.toString();
11
+ } catch (e) {
12
+ }
13
+ return [
14
+ route.entryName,
15
+ html
16
+ ];
17
+ }) || []);
18
+ const templates = Object.fromEntries(htmls);
19
+ return templates;
20
+ }
21
+ export {
22
+ getHtmlTemplates
23
+ };
@@ -2,8 +2,8 @@ import type { ServerBaseOptions, Next, Middleware, HonoEnv } from '../core/serve
2
2
  import { ServerBase } from './serverBase';
3
3
  export { createErrorHtml } from './utils';
4
4
  export { AGGRED_DIR } from './constants';
5
- export { httpCallBack2HonoMid, createNodeServer, loadServerEnv, connectMid2HonoMid, sendResponse, createStaticMiddleware, bindBFFHandler, registerMockHandlers, createInjectHtml, createWebRequest, } from './adapters/node';
6
- export { favionFallbackMiddleware, bindDataHandlers, injectReporter, getRenderHandler, injectLogger, bindRenderHandler, } from './middlewares';
5
+ export { httpCallBack2HonoMid, createNodeServer, loadServerEnv, connectMid2HonoMid, sendResponse, createStaticMiddleware, bindBFFHandler, registerMockHandlers, createInjectHtml, type ServerNodeContext, type ServerNodeMiddleware, } from './adapters/node';
6
+ export { favionFallbackMiddleware, injectReporter, getRenderHandler, injectLogger, bindRenderHandler, } from './middlewares';
7
7
  export type { BindRenderHandleOptions } from './middlewares';
8
8
  export declare function createServerBase<E extends HonoEnv>(options: ServerBaseOptions): ServerBase<E>;
9
9
  export type { ServerBaseOptions, Next, Middleware, ServerBase };
@@ -1,4 +1,3 @@
1
1
  export * from './faviconFallback';
2
- export * from './dataHandler';
3
2
  export * from './monitor';
4
3
  export * from './renderHandler';
@@ -0,0 +1,5 @@
1
+ import type { ServerRoute } from '@modern-js/types';
2
+ import { SSRRenderOptions } from './ssrRender';
3
+ export declare const dataHandler: (request: Request, { routeInfo, serverRoutes, pwd, reporter, logger, }: SSRRenderOptions & {
4
+ serverRoutes: ServerRoute[];
5
+ }) => Promise<Response | void>;
@@ -5,5 +5,5 @@ export type BindRenderHandleOptions = {
5
5
  metaName?: string;
6
6
  staticGenerate?: boolean;
7
7
  };
8
- export declare function getRenderHandler(options: ServerBaseOptions & BindRenderHandleOptions): Render | null;
8
+ export declare function getRenderHandler(options: ServerBaseOptions & BindRenderHandleOptions): Promise<Render | null>;
9
9
  export declare function bindRenderHandler(server: ServerBase, options: ServerBaseOptions & BindRenderHandleOptions): Promise<void>;
@@ -8,5 +8,5 @@ interface CreateRenderOptions {
8
8
  forceCSR?: boolean;
9
9
  nonce?: string;
10
10
  }
11
- export declare function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce, }: CreateRenderOptions): Render;
11
+ export declare function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce, }: CreateRenderOptions): Promise<Render>;
12
12
  export {};
@@ -2,9 +2,8 @@
2
2
  /// <reference types="dist/types/core/server" />
3
3
  import type { IncomingMessage } from 'http';
4
4
  import type { Logger, Reporter, ServerRoute } from '@modern-js/types';
5
- interface SSRRenderOptions {
5
+ export interface SSRRenderOptions {
6
6
  pwd: string;
7
- mode: 'string' | 'stream';
8
7
  html: string;
9
8
  routeInfo: ServerRoute;
10
9
  staticGenerate: boolean;
@@ -15,4 +14,3 @@ interface SSRRenderOptions {
15
14
  nonce?: string;
16
15
  }
17
16
  export declare function ssrRender(request: Request, { routeInfo, pwd, html, staticGenerate, nonce, metaName, reporter, logger, nodeReq, }: SSRRenderOptions): Promise<Response>;
18
- export {};
@@ -0,0 +1,2 @@
1
+ import { ServerRoute } from '@modern-js/types';
2
+ export declare function getHtmlTemplates(pwd: string, routes: ServerRoute[]): Promise<Record<string, string>>;
@@ -1,5 +1,6 @@
1
1
  export * from './core/plugin';
2
2
  export * from './core/render';
3
+ export type { HonoContext, HonoEnv, HonoMiddleware, HonoRequest, } from './core/hono';
3
4
  export * from '@modern-js/plugin';
4
5
  export * from './core/loadPlugins';
5
6
  export * from './types/config';
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.47.1-alpha.1",
18
+ "version": "2.47.1-alpha.3",
19
19
  "jsnext:source": "./src/index.ts",
20
20
  "types": "./dist/types/index.d.ts",
21
21
  "main": "./dist/cjs/index.js",
@@ -54,8 +54,8 @@
54
54
  "hono": "^3.12.2",
55
55
  "isbot": "3.8.0",
56
56
  "merge-deep": "^3.0.3",
57
- "@modern-js/runtime-utils": "2.47.0",
58
57
  "@modern-js/plugin": "2.47.0",
58
+ "@modern-js/runtime-utils": "2.47.0",
59
59
  "@modern-js/utils": "2.47.0"
60
60
  },
61
61
  "devDependencies": {
@@ -67,8 +67,8 @@
67
67
  "ts-jest": "^29.1.0",
68
68
  "typescript": "^5",
69
69
  "@modern-js/types": "2.47.0",
70
- "@scripts/build": "2.47.0",
71
- "@scripts/jest-config": "2.47.0"
70
+ "@scripts/jest-config": "2.47.0",
71
+ "@scripts/build": "2.47.0"
72
72
  },
73
73
  "sideEffects": false,
74
74
  "publishConfig": {
@@ -1,35 +0,0 @@
1
- import { MAIN_ENTRY_NAME, SERVER_BUNDLE_DIRECTORY } from "@modern-js/utils";
2
- import { getPathModule, sortRoutes } from "../utils";
3
- const bindDataHandlers = async (server, routes, distDir) => {
4
- const path = await getPathModule();
5
- routes.sort(sortRoutes).forEach((route) => {
6
- const bundlePath = path.join(distDir, SERVER_BUNDLE_DIRECTORY, `${route.entryName || MAIN_ENTRY_NAME}-server-loaders.js`);
7
- server.all(`${route.urlPath === "/" ? "*" : `${route.urlPath}/*`}`, createDataHandler(routes, bundlePath));
8
- });
9
- };
10
- const createDataHandler = (serverRoutes, buildModulePath) => {
11
- return async (context, next) => {
12
- let buildModule;
13
- try {
14
- buildModule = await import(buildModulePath);
15
- } catch (_) {
16
- return next();
17
- }
18
- const { routes, handleRequest } = buildModule;
19
- const logger = context.get("logger");
20
- const reporter = context.get("reporter");
21
- const response = await handleRequest({
22
- request: context.req.raw,
23
- serverRoutes,
24
- context: {
25
- logger,
26
- reporter
27
- },
28
- routes
29
- });
30
- return response ? response : next();
31
- };
32
- };
33
- export {
34
- bindDataHandlers
35
- };
@@ -1,3 +0,0 @@
1
- import type { ServerRoute } from '@modern-js/types';
2
- import type { ServerBase } from '../serverBase';
3
- export declare const bindDataHandlers: (server: ServerBase, routes: ServerRoute[], distDir: string) => Promise<void>;