@modern-js/server-core 2.54.5 → 2.55.0

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 (39) hide show
  1. package/dist/cjs/index.js +3 -1
  2. package/dist/cjs/plugins/render/dataHandler.js +3 -2
  3. package/dist/cjs/plugins/render/index.js +1 -1
  4. package/dist/cjs/plugins/render/render.js +37 -13
  5. package/dist/cjs/plugins/render/serverTiming.js +6 -4
  6. package/dist/cjs/plugins/render/ssrCache.js +72 -83
  7. package/dist/cjs/plugins/render/ssrRender.js +40 -145
  8. package/dist/cjs/types/requestHandler.js +16 -0
  9. package/dist/cjs/utils/transformStream.js +1 -1
  10. package/dist/esm/index.js +1 -0
  11. package/dist/esm/plugins/render/dataHandler.js +4 -3
  12. package/dist/esm/plugins/render/index.js +1 -1
  13. package/dist/esm/plugins/render/render.js +56 -22
  14. package/dist/esm/plugins/render/serverTiming.js +12 -4
  15. package/dist/esm/plugins/render/ssrCache.js +101 -131
  16. package/dist/esm/plugins/render/ssrRender.js +55 -175
  17. package/dist/esm/types/requestHandler.js +0 -0
  18. package/dist/esm/utils/transformStream.js +16 -2
  19. package/dist/esm-node/index.js +1 -0
  20. package/dist/esm-node/plugins/render/dataHandler.js +3 -2
  21. package/dist/esm-node/plugins/render/index.js +1 -1
  22. package/dist/esm-node/plugins/render/render.js +38 -14
  23. package/dist/esm-node/plugins/render/serverTiming.js +6 -4
  24. package/dist/esm-node/plugins/render/ssrCache.js +73 -74
  25. package/dist/esm-node/plugins/render/ssrRender.js +43 -137
  26. package/dist/esm-node/types/requestHandler.js +0 -0
  27. package/dist/esm-node/utils/transformStream.js +1 -1
  28. package/dist/types/index.d.ts +1 -0
  29. package/dist/types/plugins/render/dataHandler.d.ts +1 -1
  30. package/dist/types/plugins/render/render.d.ts +3 -2
  31. package/dist/types/plugins/render/serverTiming.d.ts +3 -2
  32. package/dist/types/plugins/render/ssrCache.d.ts +7 -11
  33. package/dist/types/plugins/render/ssrRender.d.ts +10 -10
  34. package/dist/types/types/config/html.d.ts +11 -0
  35. package/dist/types/types/config/output.d.ts +8 -0
  36. package/dist/types/types/requestHandler.d.ts +43 -0
  37. package/dist/types/types/server.d.ts +7 -2
  38. package/dist/types/utils/transformStream.d.ts +1 -1
  39. package/package.json +7 -8
package/dist/cjs/index.js CHANGED
@@ -36,6 +36,7 @@ __reExport(src_exports, require("./types/plugin"), module.exports);
36
36
  __reExport(src_exports, require("./types/render"), module.exports);
37
37
  __reExport(src_exports, require("@modern-js/plugin"), module.exports);
38
38
  __reExport(src_exports, require("./types/config"), module.exports);
39
+ __reExport(src_exports, require("./types/requestHandler"), module.exports);
39
40
  // Annotate the CommonJS export names for ESM import in node:
40
41
  0 && (module.exports = {
41
42
  AGGRED_DIR,
@@ -48,5 +49,6 @@ __reExport(src_exports, require("./types/config"), module.exports);
48
49
  ...require("./types/plugin"),
49
50
  ...require("./types/render"),
50
51
  ...require("@modern-js/plugin"),
51
- ...require("./types/config")
52
+ ...require("./types/config"),
53
+ ...require("./types/requestHandler")
52
54
  });
@@ -22,7 +22,7 @@ __export(dataHandler_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(dataHandler_exports);
24
24
  var import_constants = require("@modern-js/utils/universal/constants");
25
- const dataHandler = async (request, { routeInfo, serverRoutes, reporter, logger, serverManifest }) => {
25
+ const dataHandler = async (request, { routeInfo, serverRoutes, reporter, onError, onTiming, serverManifest }) => {
26
26
  var _serverManifest_loaderBundles;
27
27
  const serverLoaderModule = serverManifest === null || serverManifest === void 0 ? void 0 : (_serverManifest_loaderBundles = serverManifest.loaderBundles) === null || _serverManifest_loaderBundles === void 0 ? void 0 : _serverManifest_loaderBundles[routeInfo.entryName || import_constants.MAIN_ENTRY_NAME];
28
28
  if (!serverLoaderModule) {
@@ -33,9 +33,10 @@ const dataHandler = async (request, { routeInfo, serverRoutes, reporter, logger,
33
33
  request,
34
34
  serverRoutes,
35
35
  context: {
36
- logger,
37
36
  reporter
38
37
  },
38
+ onTiming,
39
+ onError,
39
40
  routes
40
41
  });
41
42
  return response;
@@ -120,7 +120,7 @@ async function getRenderHandler({ pwd, routes, config, cacheConfig, metaName, st
120
120
  const render = (0, import_render.createRender)({
121
121
  routes,
122
122
  pwd,
123
- // TODO: need static Genrate
123
+ config,
124
124
  staticGenerate,
125
125
  cacheConfig,
126
126
  forceCSR,
@@ -27,6 +27,7 @@ var import_utils = require("../../utils");
27
27
  var import_constants = require("../../constants");
28
28
  var import_dataHandler = require("./dataHandler");
29
29
  var import_ssrRender = require("./ssrRender");
30
+ var import_serverTiming = require("./serverTiming");
30
31
  const DYNAMIC_ROUTE_REG = /\/:./;
31
32
  function getRouter(routes) {
32
33
  const dynamicRoutes = [];
@@ -56,7 +57,16 @@ function matchRoute(router, request) {
56
57
  const result = matched[0][0];
57
58
  return result || [];
58
59
  }
59
- async function createRender({ routes, pwd, metaName, staticGenerate, cacheConfig, forceCSR, nonce, onFallback: onFallbackFn }) {
60
+ function getHeadersWithoutCookie(headers) {
61
+ const _headers = {
62
+ ...headers,
63
+ cookie: void 0
64
+ };
65
+ delete _headers.cookie;
66
+ return _headers;
67
+ }
68
+ const SERVER_TIMING = "Server-Timing";
69
+ async function createRender({ routes, pwd, metaName, staticGenerate, cacheConfig, forceCSR, config, onFallback: onFallbackFn }) {
60
70
  const router = getRouter(routes);
61
71
  return async (req, { logger, nodeReq, reporter, templates, serverManifest, locals, metrics, loaderContext }) => {
62
72
  const [routeInfo, params] = matchRoute(router, req);
@@ -85,7 +95,17 @@ async function createRender({ routes, pwd, metaName, staticGenerate, cacheConfig
85
95
  });
86
96
  }
87
97
  const renderMode = await getRenderMode(req, metaName || "modern-js", routeInfo.isSSR, forceCSR, nodeReq, onFallback);
88
- const onError = async (e) => {
98
+ const pathname = (0, import_utils.getPathname)(req);
99
+ const headerData = (0, import_utils.parseHeaders)(req);
100
+ const serverTimingInstance = new import_serverTiming.ServerTiming(metaName || "modern");
101
+ const onError = (e) => {
102
+ logger.error(`SSR Error - ${e instanceof Error ? e.name : e}, error = %s, req.url = %s, req.headers = %o`, e instanceof Error ? e.stack || e.message : e, pathname, getHeadersWithoutCookie(headerData));
103
+ };
104
+ const onTiming = (name, dur) => {
105
+ logger.debug(`SSR Debug - ${name}, cost = %s, req.url = %s`, dur, pathname);
106
+ serverTimingInstance.addServeTiming(name, dur);
107
+ };
108
+ const onBoundError = async (e) => {
89
109
  (0, import_utils.onError)(import_utils.ErrorDigest.ERENDER, e, logger, req);
90
110
  await (onFallback === null || onFallback === void 0 ? void 0 : onFallback("error", e));
91
111
  };
@@ -94,32 +114,36 @@ async function createRender({ routes, pwd, metaName, staticGenerate, cacheConfig
94
114
  html,
95
115
  routeInfo,
96
116
  staticGenerate: staticGenerate || false,
97
- metaName: metaName || "modern-js",
98
- nonce,
99
- logger,
117
+ config,
100
118
  nodeReq,
101
119
  cacheConfig,
102
120
  reporter,
103
121
  serverRoutes: routes,
104
122
  params,
123
+ logger,
124
+ metrics,
105
125
  locals,
106
126
  serverManifest,
107
- metrics,
108
- loaderContext: loaderContext || /* @__PURE__ */ new Map()
127
+ loaderContext: loaderContext || /* @__PURE__ */ new Map(),
128
+ onError,
129
+ onTiming
109
130
  };
131
+ let response;
110
132
  switch (renderMode) {
111
133
  case "data":
112
- let response = await (0, import_dataHandler.dataHandler)(req, renderOptions);
113
- if (!response) {
114
- response = await renderHandler(req, renderOptions, "ssr", onError);
115
- }
116
- return response;
134
+ response = await (0, import_dataHandler.dataHandler)(req, renderOptions) || await renderHandler(req, renderOptions, "ssr", onBoundError);
135
+ break;
117
136
  case "ssr":
118
137
  case "csr":
119
- return renderHandler(req, renderOptions, renderMode, onError);
138
+ response = await renderHandler(req, renderOptions, renderMode, onBoundError);
139
+ break;
120
140
  default:
121
141
  throw new Error(`Unknown render mode: ${renderMode}`);
122
142
  }
143
+ serverTimingInstance.headers.forEach((value) => {
144
+ response.headers.append(SERVER_TIMING, value);
145
+ });
146
+ return response;
123
147
  };
124
148
  }
125
149
  async function renderHandler(request, options, mode, onError) {
@@ -21,17 +21,19 @@ __export(serverTiming_exports, {
21
21
  ServerTiming: () => ServerTiming
22
22
  });
23
23
  module.exports = __toCommonJS(serverTiming_exports);
24
- const SERVER_TIMING = "Server-Timing";
25
24
  class ServerTiming {
25
+ get headers() {
26
+ return this.headerList;
27
+ }
26
28
  addServeTiming(name, dur, desc) {
27
29
  const _name = `bd-${this.meta}-${name}`;
28
30
  const value = `${_name};${desc ? `decs="${desc}";` : ""} dur=${dur}`;
29
- this.headers.append(SERVER_TIMING, value);
31
+ this.headerList.push(value);
30
32
  return this;
31
33
  }
32
- constructor(headers, meta) {
34
+ constructor(meta) {
35
+ this.headerList = [];
33
36
  this.meta = meta;
34
- this.headers = headers;
35
37
  }
36
38
  }
37
39
  // Annotate the CommonJS export names for ESM import in node:
@@ -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,14 +15,6 @@ 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 ssrCache_exports = {};
30
20
  __export(ssrCache_exports, {
@@ -33,72 +23,42 @@ __export(ssrCache_exports, {
33
23
  });
34
24
  module.exports = __toCommonJS(ssrCache_exports);
35
25
  var import_storer = require("@modern-js/runtime-utils/storer");
26
+ var import_constants = require("../../constants");
36
27
  var import_utils = require("../../utils");
37
- async function processCache(key, render, ssrContext, ttl, container, status) {
38
- const renderResult = await render(ssrContext);
39
- if (!renderResult) {
40
- return {
41
- data: ""
42
- };
43
- } else if (typeof renderResult === "string") {
44
- const current = Date.now();
45
- const cache = {
46
- val: renderResult,
47
- cursor: current
48
- };
49
- await container.set(key, JSON.stringify(cache), {
50
- ttl
51
- });
52
- return {
53
- data: renderResult,
54
- status
55
- };
56
- } else {
57
- const { Readable } = await Promise.resolve().then(() => __toESM(require("stream"))).catch((_) => ({
58
- Readable: void 0
59
- }));
60
- const runtimeEnv = (0, import_utils.getRuntimeEnv)();
61
- const streamModule = "../../adapters/node/polyfills/stream";
62
- const { createReadableStreamFromReadable } = runtimeEnv === "node" ? await Promise.resolve().then(() => __toESM(require(streamModule))).catch((_) => ({
63
- createReadableStreamFromReadable: void 0
64
- })) : {
65
- createReadableStreamFromReadable: void 0
66
- };
67
- const body = (
68
- // TODO: remove node:stream, move it to ssr entry.
69
- Readable && renderResult instanceof Readable ? createReadableStreamFromReadable === null || createReadableStreamFromReadable === void 0 ? void 0 : createReadableStreamFromReadable(renderResult) : renderResult
70
- );
28
+ async function processCache({ request, key, requestHandler, requestHandlerOptions, ttl, container, cacheStatus }) {
29
+ const response = await requestHandler(request, requestHandlerOptions);
30
+ const decoder = new TextDecoder();
31
+ if (response.body) {
32
+ const stream = (0, import_utils.createTransformStream)();
33
+ const reader = response.body.getReader();
34
+ const writer = stream.writable.getWriter();
71
35
  let html = "";
72
- const stream = (0, import_utils.createTransformStream)((chunk) => {
73
- html += chunk;
74
- return chunk;
36
+ const push = () => reader.read().then(({ done, value }) => {
37
+ if (done) {
38
+ const current = Date.now();
39
+ const cache = {
40
+ val: html,
41
+ cursor: current
42
+ };
43
+ container.set(key, JSON.stringify(cache), {
44
+ ttl
45
+ });
46
+ writer.close();
47
+ return;
48
+ }
49
+ const content = decoder.decode(value);
50
+ html += content;
51
+ writer.write(value);
52
+ push();
75
53
  });
76
- const reader = body.getReader();
77
- const writer = stream.writable.getWriter();
78
- const push = () => {
79
- reader.read().then(({ done, value }) => {
80
- if (done) {
81
- const current = Date.now();
82
- const cache = {
83
- val: html,
84
- cursor: current
85
- };
86
- container.set(key, JSON.stringify(cache), {
87
- ttl
88
- });
89
- writer.close();
90
- return;
91
- }
92
- writer.write(value);
93
- push();
94
- });
95
- };
96
54
  push();
97
- return {
98
- data: stream.readable,
99
- status
100
- };
55
+ cacheStatus && response.headers.set(import_constants.X_RENDER_CACHE, cacheStatus);
56
+ return new Response(stream.readable, {
57
+ status: response.status,
58
+ headers: response.headers
59
+ });
101
60
  }
61
+ return response;
102
62
  }
103
63
  const CACHE_NAMESPACE = "__ssr__cache";
104
64
  const storage = (0, import_storer.createMemoryStorage)(CACHE_NAMESPACE);
@@ -145,7 +105,7 @@ function matchCacheControl(cacheOption, req) {
145
105
  }
146
106
  }
147
107
  async function getCacheResult(request, options) {
148
- const { cacheControl, render, ssrContext, container = storage } = options;
108
+ const { cacheControl, container = storage, requestHandler, requestHandlerOptions } = options;
149
109
  const key = computedKey(request, cacheControl);
150
110
  const value = await container.get(key);
151
111
  const { maxAge, staleWhileRevalidate } = cacheControl;
@@ -154,21 +114,50 @@ async function getCacheResult(request, options) {
154
114
  const cache = JSON.parse(value);
155
115
  const interval = Date.now() - cache.cursor;
156
116
  if (interval <= maxAge) {
157
- return {
158
- data: cache.val,
159
- status: "hit"
160
- };
117
+ const cacheStatus = "hit";
118
+ return new Response(cache.val, {
119
+ headers: {
120
+ [import_constants.X_RENDER_CACHE]: cacheStatus
121
+ }
122
+ });
161
123
  } else if (interval <= staleWhileRevalidate + maxAge) {
162
- processCache(key, render, ssrContext, ttl, container);
163
- return {
164
- data: cache.val,
165
- status: "stale"
166
- };
124
+ processCache({
125
+ key,
126
+ request,
127
+ requestHandler,
128
+ requestHandlerOptions,
129
+ ttl,
130
+ container
131
+ }).then(async (response) => {
132
+ await response.text();
133
+ });
134
+ const cacheStatus = "stale";
135
+ return new Response(cache.val, {
136
+ headers: {
137
+ [import_constants.X_RENDER_CACHE]: cacheStatus
138
+ }
139
+ });
167
140
  } else {
168
- return processCache(key, render, ssrContext, ttl, container, "expired");
141
+ return processCache({
142
+ key,
143
+ request,
144
+ requestHandler,
145
+ requestHandlerOptions,
146
+ ttl,
147
+ container,
148
+ cacheStatus: "expired"
149
+ });
169
150
  }
170
151
  } else {
171
- return processCache(key, render, ssrContext, ttl, container, "miss");
152
+ return processCache({
153
+ key,
154
+ request,
155
+ requestHandler,
156
+ requestHandlerOptions,
157
+ ttl,
158
+ container,
159
+ cacheStatus: "miss"
160
+ });
172
161
  }
173
162
  }
174
163
  // Annotate the CommonJS export names for ESM import in node:
@@ -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,48 +15,22 @@ 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 ssrRender_exports = {};
30
20
  __export(ssrRender_exports, {
31
- getPathnameFromNodeReq: () => getPathnameFromNodeReq,
32
21
  ssrRender: () => ssrRender
33
22
  });
34
23
  module.exports = __toCommonJS(ssrRender_exports);
35
24
  var import_constants = require("@modern-js/utils/universal/constants");
36
- var isbot = __toESM(require("isbot"));
37
25
  var import_utils = require("../../utils");
38
26
  var import_constants2 = require("../../constants");
39
- var import_serverTiming = require("./serverTiming");
40
27
  var import_ssrCache = require("./ssrCache");
41
- const defaultReporter = {
42
- init() {
43
- },
44
- reportError() {
45
- },
46
- reportTiming() {
47
- },
48
- reportInfo() {
49
- },
50
- reportWarn() {
51
- }
52
- };
53
- async function ssrRender(request, { routeInfo, html, staticGenerate, nonce, metaName, reporter, logger, nodeReq, serverManifest, locals, params, metrics, loaderContext, cacheConfig }) {
28
+ const SERVER_RUNTIME_ENTRY = "requestHandler";
29
+ async function ssrRender(request, { routeInfo, html, config: userConfig, staticGenerate, nodeReq, serverManifest, locals, params, loaderContext, reporter, cacheConfig, logger, metrics, onError, onTiming }) {
54
30
  var _serverManifest_renderBundles;
55
31
  const { entryName } = routeInfo;
56
32
  const loadableStats = serverManifest.loadableStats || {};
57
33
  const routeManifest = serverManifest.routeManifest || {};
58
- const host = (0, import_utils.getHost)(request);
59
- const isSpider = isbot.default(request.headers.get("user-agent"));
60
- const responseProxy = new ResponseProxy();
61
- const query = (0, import_utils.parseQuery)(request);
62
34
  const headers = (0, import_utils.parseHeaders)(request);
63
35
  if (nodeReq) {
64
36
  for (const key in nodeReq.headers) {
@@ -67,103 +39,46 @@ async function ssrRender(request, { routeInfo, html, staticGenerate, nonce, meta
67
39
  }
68
40
  }
69
41
  }
70
- const ssrContext = {
71
- request: {
72
- baseUrl: routeInfo.urlPath,
73
- params,
74
- pathname: nodeReq ? getPathnameFromNodeReq(nodeReq) : (0, import_utils.getPathname)(request),
75
- host,
76
- query,
77
- url: nodeReq ? getHrefFromNodeReq(nodeReq) : request.url,
78
- headers
79
- },
80
- response: {
81
- setHeader(key, value) {
82
- responseProxy.headers.set(key, value);
83
- },
84
- status(code) {
85
- responseProxy.status = code;
86
- },
87
- locals: locals || {}
42
+ const renderBundle = (_serverManifest_renderBundles = serverManifest.renderBundles) === null || _serverManifest_renderBundles === void 0 ? void 0 : _serverManifest_renderBundles[entryName || import_constants.MAIN_ENTRY_NAME];
43
+ if (!renderBundle) {
44
+ throw new Error(`Can't found renderBundle ${entryName || import_constants.MAIN_ENTRY_NAME}`);
45
+ }
46
+ const requestHandler = await renderBundle[SERVER_RUNTIME_ENTRY];
47
+ const config = createRequestHandlerConfig(userConfig);
48
+ const requestHandlerOptions = {
49
+ resource: {
50
+ route: routeInfo,
51
+ loadableStats,
52
+ routeManifest,
53
+ htmlTemplate: html,
54
+ entryName: entryName || import_constants.MAIN_ENTRY_NAME
88
55
  },
89
- redirection: {},
90
- template: html,
91
- loadableStats,
56
+ params,
92
57
  loaderContext,
93
- routeManifest,
94
- entryName,
58
+ config,
59
+ locals,
60
+ reporter,
95
61
  staticGenerate,
96
62
  logger,
97
63
  metrics,
98
- serverTiming: new import_serverTiming.ServerTiming(responseProxy.headers, metaName),
99
- reporter: reporter || defaultReporter,
100
- /** @deprecated node req */
101
- req: nodeReq || request,
102
- /** @deprecated node res */
103
- res: void 0,
104
- isSpider,
105
- nonce
64
+ onError,
65
+ onTiming
106
66
  };
107
- const renderBundle = (_serverManifest_renderBundles = serverManifest.renderBundles) === null || _serverManifest_renderBundles === void 0 ? void 0 : _serverManifest_renderBundles[entryName || import_constants.MAIN_ENTRY_NAME];
108
- if (!renderBundle) {
109
- throw new Error(`Can't found renderBundle ${entryName || import_constants.MAIN_ENTRY_NAME}`);
110
- }
111
- const runtimeEnv = (0, import_utils.getRuntimeEnv)();
112
- let ssrResult;
113
- let cacheStatus;
114
- const render = renderBundle[import_constants.SERVER_RENDER_FUNCTION_NAME];
115
67
  const cacheControl = await (0, import_ssrCache.matchCacheControl)(cacheConfig === null || cacheConfig === void 0 ? void 0 : cacheConfig.strategy, nodeReq || new IncomingMessgeProxy(request));
68
+ let response;
116
69
  if (cacheControl) {
117
- const { data: data2, status } = await (0, import_ssrCache.getCacheResult)(request, {
70
+ response = await (0, import_ssrCache.getCacheResult)(request, {
118
71
  cacheControl,
119
72
  container: cacheConfig === null || cacheConfig === void 0 ? void 0 : cacheConfig.container,
120
- render,
121
- ssrContext
73
+ requestHandler,
74
+ requestHandlerOptions
122
75
  });
123
- ssrResult = data2;
124
- cacheStatus = status;
125
76
  } else {
126
- ssrResult = await render(ssrContext);
127
- }
128
- const { redirection } = ssrContext;
129
- if (cacheStatus) {
130
- responseProxy.headers.set(import_constants2.X_RENDER_CACHE, cacheStatus);
131
- }
132
- responseProxy.headers.set(import_constants2.X_MODERNJS_RENDER, "server");
133
- if (redirection.url) {
134
- const { headers: headers2 } = responseProxy;
135
- headers2.set("Location", redirection.url);
136
- return new Response(null, {
137
- status: redirection.status || 302,
138
- headers: {
139
- Location: redirection.url
140
- }
141
- });
142
- }
143
- const { Readable } = await Promise.resolve().then(() => __toESM(require("stream"))).catch((_) => ({
144
- Readable: void 0
145
- }));
146
- const streamModule = "../../adapters/node/polyfills/stream";
147
- const { createReadableStreamFromReadable } = runtimeEnv === "node" ? await Promise.resolve().then(() => __toESM(require(streamModule))).catch((_) => ({
148
- createReadableStreamFromReadable: void 0
149
- })) : {
150
- createReadableStreamFromReadable: void 0
151
- };
152
- const data = Readable && ssrResult instanceof Readable ? (createReadableStreamFromReadable === null || createReadableStreamFromReadable === void 0 ? void 0 : createReadableStreamFromReadable(ssrResult)) || "" : ssrResult;
153
- if (typeof data !== "string") {
154
- responseProxy.headers.set("transfer-encoding", "chunked");
155
- }
156
- return new Response(data, {
157
- status: responseProxy.status,
158
- headers: responseProxy.headers
159
- });
160
- }
161
- class ResponseProxy {
162
- constructor() {
163
- this.headers = new Headers();
164
- this.status = 200;
165
- this.headers.set("content-type", "text/html; charset=UTF-8");
77
+ response = await requestHandler(request, requestHandlerOptions);
166
78
  }
79
+ response.headers.set(import_constants2.X_MODERNJS_RENDER, "server");
80
+ response.headers.set("content-type", "text/html; charset=UTF-8");
81
+ return response;
167
82
  }
168
83
  class IncomingMessgeProxy {
169
84
  constructor(req) {
@@ -175,39 +90,19 @@ class IncomingMessgeProxy {
175
90
  this.url = (0, import_utils.getPathname)(req);
176
91
  }
177
92
  }
178
- function getHrefFromNodeReq(nodeReq) {
179
- function getProtocal() {
180
- if (nodeReq.socket.encrypted) {
181
- return "https";
182
- }
183
- const proto = nodeReq.headers["x-forwarded-proto"];
184
- return proto ? proto.split(/\s*,\s*/, 1)[0] : "http";
185
- }
186
- function getHost2() {
187
- let host = nodeReq.headers["x-forwarded-host"];
188
- if (!host) {
189
- host = nodeReq.headers.host;
190
- }
191
- host = host.split(/\s*,\s*/, 1)[0] || "undefined";
192
- return host;
193
- }
194
- const href = `${getProtocal()}://${getHost2()}${nodeReq.url || ""}`;
195
- return href;
196
- }
197
- function getPathnameFromNodeReq(nodeReq) {
198
- const { url } = nodeReq;
199
- if (!url) {
200
- return "/";
201
- }
202
- const match = url.match(/\/[^?]*/);
203
- let pathname = match ? match[0] : "/";
204
- if (pathname !== "/" && pathname.endsWith("/")) {
205
- pathname = pathname.slice(0, -1);
206
- }
207
- return pathname;
93
+ function createRequestHandlerConfig(userConfig) {
94
+ const { output, server, security, html } = userConfig;
95
+ return {
96
+ ssr: server === null || server === void 0 ? void 0 : server.ssr,
97
+ ssrByEntries: server === null || server === void 0 ? void 0 : server.ssrByEntries,
98
+ nonce: security === null || security === void 0 ? void 0 : security.nonce,
99
+ enableInlineScripts: output === null || output === void 0 ? void 0 : output.enableInlineScripts,
100
+ enableInlineStyles: output === null || output === void 0 ? void 0 : output.enableInlineStyles,
101
+ crossorigin: html === null || html === void 0 ? void 0 : html.crossorigin,
102
+ scriptLoading: html === null || html === void 0 ? void 0 : html.scriptLoading
103
+ };
208
104
  }
209
105
  // Annotate the CommonJS export names for ESM import in node:
210
106
  0 && (module.exports = {
211
- getPathnameFromNodeReq,
212
107
  ssrRender
213
108
  });
@@ -0,0 +1,16 @@
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 __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var requestHandler_exports = {};
16
+ module.exports = __toCommonJS(requestHandler_exports);
@@ -28,7 +28,7 @@ function createTransformStream(fn) {
28
28
  return new TransformStream({
29
29
  async transform(chunk, controller) {
30
30
  const content = decoder.decode(chunk);
31
- const newContent = await fn(content);
31
+ const newContent = fn ? await fn(content) : content;
32
32
  controller.enqueue(encoder.encode(newContent));
33
33
  }
34
34
  });
package/dist/esm/index.js CHANGED
@@ -7,6 +7,7 @@ export * from "./types/plugin";
7
7
  export * from "./types/render";
8
8
  export * from "@modern-js/plugin";
9
9
  export * from "./types/config";
10
+ export * from "./types/requestHandler";
10
11
  export {
11
12
  AGGRED_DIR,
12
13
  ErrorDigest,
@@ -3,11 +3,11 @@ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
3
3
  import { MAIN_ENTRY_NAME } from "@modern-js/utils/universal/constants";
4
4
  var dataHandler = function() {
5
5
  var _ref = _async_to_generator(function(request, param) {
6
- var routeInfo, serverRoutes, reporter, logger, serverManifest, _serverManifest_loaderBundles, serverLoaderModule, routes, handleRequest, response;
6
+ var routeInfo, serverRoutes, reporter, onError, onTiming, serverManifest, _serverManifest_loaderBundles, serverLoaderModule, routes, handleRequest, response;
7
7
  return _ts_generator(this, function(_state) {
8
8
  switch (_state.label) {
9
9
  case 0:
10
- routeInfo = param.routeInfo, serverRoutes = param.serverRoutes, reporter = param.reporter, logger = param.logger, serverManifest = param.serverManifest;
10
+ routeInfo = param.routeInfo, serverRoutes = param.serverRoutes, reporter = param.reporter, onError = param.onError, onTiming = param.onTiming, serverManifest = param.serverManifest;
11
11
  serverLoaderModule = serverManifest === null || serverManifest === void 0 ? void 0 : (_serverManifest_loaderBundles = serverManifest.loaderBundles) === null || _serverManifest_loaderBundles === void 0 ? void 0 : _serverManifest_loaderBundles[routeInfo.entryName || MAIN_ENTRY_NAME];
12
12
  if (!serverLoaderModule) {
13
13
  return [
@@ -21,9 +21,10 @@ var dataHandler = function() {
21
21
  request,
22
22
  serverRoutes,
23
23
  context: {
24
- logger,
25
24
  reporter
26
25
  },
26
+ onTiming,
27
+ onError,
27
28
  routes
28
29
  })
29
30
  ];