@modern-js/server-core 2.49.4-alpha.2 → 2.49.5-alpha.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 (55) hide show
  1. package/dist/cjs/base/adapters/node/node.js +19 -2
  2. package/dist/cjs/base/adapters/node/polyfills/stream.js +18 -11
  3. package/dist/cjs/base/index.js +2 -0
  4. package/dist/cjs/base/middlewares/customServer/base.js +14 -4
  5. package/dist/cjs/base/middlewares/customServer/context.js +2 -2
  6. package/dist/cjs/base/middlewares/customServer/index.js +65 -11
  7. package/dist/cjs/base/middlewares/customServer/loader.js +37 -0
  8. package/dist/cjs/base/middlewares/index.js +9 -0
  9. package/dist/cjs/base/middlewares/renderHandler/index.js +16 -3
  10. package/dist/cjs/base/middlewares/renderHandler/render.js +4 -3
  11. package/dist/cjs/base/middlewares/renderHandler/ssrCache.js +1 -1
  12. package/dist/cjs/base/middlewares/renderHandler/ssrRender.js +2 -1
  13. package/dist/cjs/base/utils/index.js +3 -3
  14. package/dist/cjs/base/utils/request.js +19 -6
  15. package/dist/esm/base/adapters/node/node.js +50 -11
  16. package/dist/esm/base/adapters/node/polyfills/stream.js +56 -32
  17. package/dist/esm/base/index.js +2 -1
  18. package/dist/esm/base/middlewares/customServer/base.js +14 -4
  19. package/dist/esm/base/middlewares/customServer/context.js +2 -2
  20. package/dist/esm/base/middlewares/customServer/index.js +127 -47
  21. package/dist/esm/base/middlewares/customServer/loader.js +13 -0
  22. package/dist/esm/base/middlewares/index.js +4 -0
  23. package/dist/esm/base/middlewares/renderHandler/index.js +81 -28
  24. package/dist/esm/base/middlewares/renderHandler/render.js +5 -4
  25. package/dist/esm/base/middlewares/renderHandler/ssrCache.js +1 -1
  26. package/dist/esm/base/middlewares/renderHandler/ssrRender.js +3 -2
  27. package/dist/esm/base/utils/index.js +1 -1
  28. package/dist/esm/base/utils/request.js +18 -6
  29. package/dist/esm-node/base/adapters/node/node.js +10 -3
  30. package/dist/esm-node/base/adapters/node/polyfills/stream.js +18 -11
  31. package/dist/esm-node/base/index.js +2 -1
  32. package/dist/esm-node/base/middlewares/customServer/base.js +14 -4
  33. package/dist/esm-node/base/middlewares/customServer/context.js +2 -2
  34. package/dist/esm-node/base/middlewares/customServer/index.js +63 -10
  35. package/dist/esm-node/base/middlewares/customServer/loader.js +13 -0
  36. package/dist/esm-node/base/middlewares/index.js +4 -0
  37. package/dist/esm-node/base/middlewares/renderHandler/index.js +17 -4
  38. package/dist/esm-node/base/middlewares/renderHandler/render.js +4 -3
  39. package/dist/esm-node/base/middlewares/renderHandler/ssrCache.js +1 -1
  40. package/dist/esm-node/base/middlewares/renderHandler/ssrRender.js +2 -1
  41. package/dist/esm-node/base/utils/index.js +1 -1
  42. package/dist/esm-node/base/utils/request.js +18 -6
  43. package/dist/types/base/adapters/node/node.d.ts +4 -2
  44. package/dist/types/base/index.d.ts +1 -1
  45. package/dist/types/base/middlewares/customServer/base.d.ts +5 -1
  46. package/dist/types/base/middlewares/customServer/context.d.ts +2 -1
  47. package/dist/types/base/middlewares/customServer/index.d.ts +2 -1
  48. package/dist/types/base/middlewares/customServer/loader.d.ts +10 -0
  49. package/dist/types/base/middlewares/index.d.ts +1 -0
  50. package/dist/types/base/middlewares/renderHandler/ssrRender.d.ts +2 -1
  51. package/dist/types/base/utils/index.d.ts +1 -1
  52. package/dist/types/base/utils/request.d.ts +7 -2
  53. package/dist/types/core/plugin.d.ts +8 -8
  54. package/dist/types/core/render.d.ts +1 -0
  55. package/package.json +7 -7
@@ -1,7 +1,7 @@
1
1
  export * from "./env";
2
- export * from "./request";
3
2
  export * from "./transformStream";
4
3
  export * from "./middlewareCollector";
5
4
  export * from "./error";
6
5
  export * from "./warmup";
7
6
  export * from "./entry";
7
+ export * from "./request";
@@ -1,12 +1,12 @@
1
1
  import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
2
- function parseQuery(request) {
3
- var url = request.url;
4
- var q = url.split("?")[1];
2
+ function parseQuery(req) {
5
3
  var query = {};
4
+ var url = req.url;
5
+ var q = url.split("?")[1];
6
6
  if (q) {
7
- q.split("&").forEach(function(item) {
8
- var _item_split = _sliced_to_array(item.split("="), 2), key = _item_split[0], value = _item_split[1];
9
- query[key] = value;
7
+ var search = new URLSearchParams(q);
8
+ search.forEach(function(v, k) {
9
+ query[k] = v;
10
10
  });
11
11
  }
12
12
  return query;
@@ -31,9 +31,21 @@ function getHost(request) {
31
31
  host = (host === null || host === void 0 ? void 0 : host.split(/\s*,\s*/, 1)[0]) || "undefined";
32
32
  return host;
33
33
  }
34
+ function parseCookie(req) {
35
+ var _cookie = req.headers.get("Cookie");
36
+ var cookie = {};
37
+ _cookie === null || _cookie === void 0 ? void 0 : _cookie.trim().split(";").forEach(function(item) {
38
+ var _item_trim_split = _sliced_to_array(item.trim().split("="), 2), k = _item_trim_split[0], v = _item_trim_split[1];
39
+ if (k) {
40
+ cookie[k] = v;
41
+ }
42
+ });
43
+ return cookie;
44
+ }
34
45
  export {
35
46
  getHost,
36
47
  getPathname,
48
+ parseCookie,
37
49
  parseHeaders,
38
50
  parseQuery
39
51
  };
@@ -1,4 +1,4 @@
1
- import { createServer, ServerResponse } from "node:http";
1
+ import { ServerResponse } from "node:http";
2
2
  import { createReadableStreamFromReadable, writeReadableStreamToWritable } from "./polyfills/stream";
3
3
  import { installGlobals } from "./polyfills/install";
4
4
  installGlobals();
@@ -87,9 +87,16 @@ const getRequestListener = (handler) => {
87
87
  }
88
88
  };
89
89
  };
90
- const createNodeServer = (requestHandler) => {
90
+ const createNodeServer = async (requestHandler, httpsOptions) => {
91
91
  const requestListener = getRequestListener(requestHandler);
92
- const nodeServer = createServer(requestListener);
92
+ let nodeServer;
93
+ if (httpsOptions) {
94
+ const { createServer } = await import("node:https");
95
+ nodeServer = createServer(httpsOptions, requestListener);
96
+ } else {
97
+ const { createServer } = await import("node:http");
98
+ nodeServer = createServer(requestListener);
99
+ }
93
100
  nodeServer.getRequestListener = () => requestListener;
94
101
  nodeServer.getRequestHandler = () => requestHandler;
95
102
  return nodeServer;
@@ -3,17 +3,24 @@ async function writeReadableStreamToWritable(stream, writable) {
3
3
  const reader = stream.getReader();
4
4
  const flushable = writable;
5
5
  try {
6
- while (true) {
7
- const { done, value } = await reader.read();
8
- if (done) {
9
- writable.end();
10
- break;
11
- }
12
- writable.write(value);
13
- if (typeof flushable.flush === "function") {
14
- flushable.flush();
15
- }
16
- }
6
+ await new Promise((resolve, reject) => {
7
+ writable.on("finish", resolve);
8
+ writable.on("error", reject);
9
+ const writeAndFlush = async () => {
10
+ while (true) {
11
+ const { done, value } = await reader.read();
12
+ if (done) {
13
+ writable.end();
14
+ break;
15
+ }
16
+ writable.write(value);
17
+ if (typeof flushable.flush === "function") {
18
+ flushable.flush();
19
+ }
20
+ }
21
+ };
22
+ writeAndFlush().catch(reject);
23
+ });
17
24
  } catch (error) {
18
25
  writable.destroy(error);
19
26
  throw error;
@@ -1,6 +1,6 @@
1
1
  import { createErrorHtml, onError, ErrorDigest } from "./utils";
2
2
  import { AGGRED_DIR } from "./constants";
3
- import { favionFallbackMiddleware, injectReporter, injectLogger, getRenderHandler, bindRenderHandler, logHandler, processedBy } from "./middlewares";
3
+ import { favionFallbackMiddleware, injectReporter, injectLogger, getRenderHandler, bindRenderHandler, logHandler, processedBy, getLoaderCtx } from "./middlewares";
4
4
  import { createServerBase } from "./serverBase";
5
5
  export {
6
6
  AGGRED_DIR,
@@ -9,6 +9,7 @@ export {
9
9
  createErrorHtml,
10
10
  createServerBase,
11
11
  favionFallbackMiddleware,
12
+ getLoaderCtx,
12
13
  getRenderHandler,
13
14
  injectLogger,
14
15
  injectReporter,
@@ -3,12 +3,12 @@ import { _ as _class_private_field_init } from "@swc/helpers/_/_class_private_fi
3
3
  import { _ as _class_private_field_set } from "@swc/helpers/_/_class_private_field_set";
4
4
  import { getCookie } from "hono/cookie";
5
5
  import { getHost } from "../../utils";
6
- function createBaseHookContext(c) {
6
+ function createBaseHookContext(c, resParams) {
7
7
  const logger = c.get("logger");
8
8
  const metrics = c.get("metrics");
9
9
  return {
10
10
  request: new BaseHookRequest(c),
11
- response: new BaseHookResponse(c),
11
+ response: new BaseHookResponse(c, resParams),
12
12
  logger,
13
13
  metrics
14
14
  };
@@ -95,7 +95,7 @@ class BaseHookRequest {
95
95
  }));
96
96
  }
97
97
  }
98
- var _c1 = /* @__PURE__ */ new WeakMap();
98
+ var _c1 = /* @__PURE__ */ new WeakMap(), _resArgs = /* @__PURE__ */ new WeakMap();
99
99
  class BaseHookResponse {
100
100
  get(key) {
101
101
  return _class_private_field_get(this, _c1).res.headers.get(key);
@@ -105,15 +105,20 @@ class BaseHookResponse {
105
105
  "set-cookie",
106
106
  "Set-Cookie"
107
107
  ].includes(key)) {
108
+ var _class_private_field_get1;
108
109
  _class_private_field_get(this, _c1).header(key, value.toString(), {
109
110
  append: true
110
111
  });
112
+ (_class_private_field_get1 = _class_private_field_get(this, _resArgs)) === null || _class_private_field_get1 === void 0 ? void 0 : _class_private_field_get1.headers.append(key, value.toString());
111
113
  } else {
114
+ var _class_private_field_get2;
112
115
  _class_private_field_get(this, _c1).header(key, value.toString());
116
+ (_class_private_field_get2 = _class_private_field_get(this, _resArgs)) === null || _class_private_field_get2 === void 0 ? void 0 : _class_private_field_get2.headers.set(key, value.toString());
113
117
  }
114
118
  }
115
119
  status(code) {
116
120
  _class_private_field_get(this, _c1).status(code);
121
+ _class_private_field_get(this, _resArgs) && (_class_private_field_get(this, _resArgs).status = code);
117
122
  }
118
123
  get cookies() {
119
124
  const setCookie = (key, value) => {
@@ -133,13 +138,18 @@ class BaseHookResponse {
133
138
  _class_private_field_get(this, _c1).res = _class_private_field_get(this, _c1).newResponse(body, options);
134
139
  this.private_overrided = true;
135
140
  }
136
- constructor(c) {
141
+ constructor(c, resArgs) {
137
142
  _class_private_field_init(this, _c1, {
138
143
  writable: true,
139
144
  value: void 0
140
145
  });
146
+ _class_private_field_init(this, _resArgs, {
147
+ writable: true,
148
+ value: void 0
149
+ });
141
150
  this.private_overrided = false;
142
151
  _class_private_field_set(this, _c1, c);
152
+ _class_private_field_set(this, _resArgs, resArgs);
143
153
  }
144
154
  }
145
155
  export {
@@ -13,9 +13,9 @@ async function getAfterRenderCtx(c, baseHookCtx, route) {
13
13
  afterRenderCtx.route = route;
14
14
  return afterRenderCtx;
15
15
  }
16
- function createCustomMiddlewaresCtx(c, locals) {
16
+ function createCustomMiddlewaresCtx(c, locals, resArgs) {
17
17
  var _c_env_node, _c_env_node1;
18
- const baseContext = createBaseHookContext(c);
18
+ const baseContext = createBaseHookContext(c, resArgs);
19
19
  const reporter = c.get("reporter");
20
20
  const response = baseContext.response;
21
21
  response.locals = locals;
@@ -1,8 +1,10 @@
1
1
  import { time } from "@modern-js/runtime-utils/time";
2
2
  import { transformResponse } from "../../utils";
3
3
  import { ServerReportTimings } from "../../constants";
4
+ import { getLoaderCtx } from "./loader";
4
5
  import { getAfterMatchCtx, getAfterRenderCtx, createCustomMiddlewaresCtx, createAfterStreamingRenderContext } from "./context";
5
6
  import { createBaseHookContext } from "./base";
7
+ import { getLoaderCtx as getLoaderCtx2 } from "./loader";
6
8
  const noop = () => {
7
9
  };
8
10
  const isHtmlResponse = (response) => {
@@ -70,22 +72,31 @@ class CustomServer {
70
72
  }
71
73
  };
72
74
  }
73
- getServerMiddleware() {
75
+ async getServerMiddleware() {
76
+ const serverMiddleware = await this.serverMiddlewarePromise;
77
+ if (!serverMiddleware) {
78
+ return;
79
+ }
80
+ if (Array.isArray(serverMiddleware)) {
81
+ return getUnstableMiddlewares(serverMiddleware);
82
+ }
74
83
  return async (c, next) => {
75
- var _c_env;
76
- const serverMiddleware = await this.serverMiddlewarePromise;
77
- if (!serverMiddleware) {
78
- return next();
79
- }
84
+ var _c_env_node_res, _c_env_node, _c_env;
80
85
  const reporter = c.get("reporter");
81
86
  const locals = {};
82
- const customMiddlewareCtx = createCustomMiddlewaresCtx(c, locals);
87
+ const resArgs = {
88
+ headers: new Headers()
89
+ };
90
+ const customMiddlewareCtx = createCustomMiddlewaresCtx(c, locals, resArgs);
83
91
  const getCost = time();
84
92
  await serverMiddleware(customMiddlewareCtx);
85
93
  const cost = getCost();
86
94
  cost && (reporter === null || reporter === void 0 ? void 0 : reporter.reportTiming(ServerReportTimings.SERVER_MIDDLEWARE, cost));
87
95
  c.set("locals", locals);
88
- if ((_c_env = c.env) === null || _c_env === void 0 ? void 0 : _c_env.node.res.headersSent) {
96
+ if (isRedirect(resArgs.headers, resArgs.status)) {
97
+ return c.redirect(resArgs.headers.get("Location") || "", resArgs.status || 302);
98
+ }
99
+ if ((_c_env = c.env) === null || _c_env === void 0 ? void 0 : (_c_env_node = _c_env.node) === null || _c_env_node === void 0 ? void 0 : (_c_env_node_res = _c_env_node.res) === null || _c_env_node_res === void 0 ? void 0 : _c_env_node_res.headersSent) {
89
100
  return void 0;
90
101
  }
91
102
  if (!c.finalized) {
@@ -103,10 +114,52 @@ class CustomServer {
103
114
  middleware: webExtension
104
115
  }
105
116
  }, {
106
- onLast: () => null
117
+ onLast: () => []
107
118
  });
108
119
  }
109
120
  }
121
+ function isRedirect(headers, code) {
122
+ return [
123
+ 301,
124
+ 302,
125
+ 307,
126
+ 308
127
+ ].includes(code || 0) || headers.get("Location");
128
+ }
129
+ function getUnstableMiddlewares(serverMiddleware) {
130
+ return serverMiddleware.map((middleware) => {
131
+ return async (c, next) => {
132
+ const context = createMiddlewareContextFromHono(c);
133
+ return middleware(context, next);
134
+ };
135
+ });
136
+ }
137
+ function createMiddlewareContextFromHono(c) {
138
+ const loaderContext = getLoaderCtx(c);
139
+ return {
140
+ get request() {
141
+ return c.req.raw;
142
+ },
143
+ get response() {
144
+ return c.res;
145
+ },
146
+ set response(newRes) {
147
+ c.res = newRes;
148
+ },
149
+ get(key) {
150
+ return loaderContext.get(key);
151
+ },
152
+ set(key, value) {
153
+ return loaderContext.set(key, value);
154
+ },
155
+ status: c.status.bind(c),
156
+ header: c.header.bind(c),
157
+ body: c.body.bind(c),
158
+ html: c.html.bind(c),
159
+ redirect: c.redirect.bind(c)
160
+ };
161
+ }
110
162
  export {
111
- CustomServer
163
+ CustomServer,
164
+ getLoaderCtx2 as getLoaderCtx
112
165
  };
@@ -0,0 +1,13 @@
1
+ function getLoaderCtx(c) {
2
+ const loaderContext = c.get("loaderContext");
3
+ if (loaderContext) {
4
+ return loaderContext;
5
+ } else {
6
+ const loaderContext2 = /* @__PURE__ */ new Map();
7
+ c.set("loaderContext", loaderContext2);
8
+ return loaderContext2;
9
+ }
10
+ }
11
+ export {
12
+ getLoaderCtx
13
+ };
@@ -3,3 +3,7 @@ export * from "./monitor";
3
3
  export * from "./renderHandler";
4
4
  export * from "./logger";
5
5
  export * from "./frameworkHeader";
6
+ import { getLoaderCtx } from "./customServer";
7
+ export {
8
+ getLoaderCtx
9
+ };
@@ -1,6 +1,6 @@
1
1
  import { checkIsProd, sortRoutes, getRuntimeEnv } from "../../utils";
2
2
  import { initReporter } from "../monitor";
3
- import { CustomServer } from "../customServer";
3
+ import { CustomServer, getLoaderCtx } from "../customServer";
4
4
  import { createRender } from "./render";
5
5
  function createRenderHandler(render) {
6
6
  return async (c, _) => {
@@ -11,6 +11,7 @@ function createRenderHandler(render) {
11
11
  const serverManifest = c.get("serverManifest") || {};
12
12
  const locals = c.get("locals");
13
13
  const metrics = c.get("metrics");
14
+ const loaderContext = getLoaderCtx(c);
14
15
  const request = c.req.raw;
15
16
  const nodeReq = (_c_env_node = c.env.node) === null || _c_env_node === void 0 ? void 0 : _c_env_node.req;
16
17
  const res = await render(request, {
@@ -20,9 +21,15 @@ function createRenderHandler(render) {
20
21
  templates,
21
22
  metrics,
22
23
  serverManifest,
24
+ loaderContext,
23
25
  locals
24
26
  });
25
- return res;
27
+ const { body, status, headers } = res;
28
+ const headersData = {};
29
+ headers.forEach((v, k) => {
30
+ headersData[k] = v;
31
+ });
32
+ return c.body(body, status, headersData);
26
33
  };
27
34
  }
28
35
  async function getRenderHandler(options, serverBase) {
@@ -69,8 +76,14 @@ async function bindRenderHandler(server, options) {
69
76
  const customServerHookMiddleware = customServer.getHookMiddleware(entryName || "main", routes);
70
77
  server.use(urlPath, initReporter(entryName));
71
78
  !disableCustomHook && server.use(urlPath, customServerHookMiddleware);
72
- const customServerMiddleware = customServer.getServerMiddleware();
73
- server.use(urlPath, customServerMiddleware);
79
+ const customServerMiddleware = await customServer.getServerMiddleware();
80
+ if (customServerMiddleware) {
81
+ if (Array.isArray(customServerMiddleware)) {
82
+ server.use(urlPath, ...customServerMiddleware);
83
+ } else {
84
+ server.use(urlPath, customServerMiddleware);
85
+ }
86
+ }
74
87
  render && server.all(urlPath, createRenderHandler(render));
75
88
  }
76
89
  }
@@ -1,7 +1,7 @@
1
1
  import { cutNameByHyphen } from "@modern-js/utils/universal";
2
2
  import { TrieRouter } from "hono/router/trie-router";
3
+ import { parseQuery, getPathname, createErrorHtml, sortRoutes, transformResponse, onError as onErrorFn, ErrorDigest } from "../../utils";
3
4
  import { REPLACE_REG } from "../../../base/constants";
4
- import { createErrorHtml, sortRoutes, parseQuery, transformResponse, getPathname, onError as onErrorFn, ErrorDigest } from "../../utils";
5
5
  import { dataHandler } from "./dataHandler";
6
6
  import { ssrRender } from "./ssrRender";
7
7
  function getRouter(routes) {
@@ -22,7 +22,7 @@ function matchRoute(router, request) {
22
22
  }
23
23
  async function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, nonce, onFallback: onFallbackFn }) {
24
24
  const router = getRouter(routes);
25
- return async (req, { logger, nodeReq, reporter, templates, serverManifest, locals, metrics }) => {
25
+ return async (req, { logger, nodeReq, reporter, templates, serverManifest, locals, metrics, loaderContext }) => {
26
26
  const [routeInfo, params] = matchRoute(router, req);
27
27
  const onFallback = async (reason, error) => {
28
28
  return onFallbackFn === null || onFallbackFn === void 0 ? void 0 : onFallbackFn(reason, {
@@ -67,7 +67,8 @@ async function createRender({ routes, pwd, metaName, staticGenerate, forceCSR, n
67
67
  params,
68
68
  locals,
69
69
  serverManifest,
70
- metrics
70
+ metrics,
71
+ loaderContext: loaderContext || /* @__PURE__ */ new Map()
71
72
  };
72
73
  switch (renderMode) {
73
74
  case "data":
@@ -1,8 +1,8 @@
1
1
  import { Readable } from "stream";
2
2
  import { SERVER_DIR, requireExistModule } from "@modern-js/utils";
3
3
  import { createMemoryStorage } from "@modern-js/runtime-utils/storer";
4
- import { createReadableStreamFromReadable } from "../../adapters/node/polyfills/stream";
5
4
  import { createTransformStream, getPathname } from "../../utils";
5
+ import { createReadableStreamFromReadable } from "../../adapters/node/polyfills/stream";
6
6
  class CacheManager {
7
7
  async getCacheResult(req, cacheControl, render, ssrContext) {
8
8
  const key = this.computedKey(req, cacheControl);
@@ -15,7 +15,7 @@ const defaultReporter = {
15
15
  reportWarn() {
16
16
  }
17
17
  };
18
- async function ssrRender(request, { routeInfo, html, staticGenerate, nonce, metaName, reporter, logger, nodeReq, serverManifest, locals, params, metrics }) {
18
+ async function ssrRender(request, { routeInfo, html, staticGenerate, nonce, metaName, reporter, logger, nodeReq, serverManifest, locals, params, metrics, loaderContext }) {
19
19
  var _serverManifest_renderBundles;
20
20
  const { entryName } = routeInfo;
21
21
  const loadableStats = serverManifest.loadableStats || {};
@@ -54,6 +54,7 @@ async function ssrRender(request, { routeInfo, html, staticGenerate, nonce, meta
54
54
  redirection: {},
55
55
  template: html,
56
56
  loadableStats,
57
+ loaderContext,
57
58
  routeManifest,
58
59
  entryName,
59
60
  staticGenerate,
@@ -1,7 +1,7 @@
1
1
  export * from "./env";
2
- export * from "./request";
3
2
  export * from "./transformStream";
4
3
  export * from "./middlewareCollector";
5
4
  export * from "./error";
6
5
  export * from "./warmup";
7
6
  export * from "./entry";
7
+ export * from "./request";
@@ -1,11 +1,11 @@
1
- function parseQuery(request) {
2
- const { url } = request;
3
- const q = url.split("?")[1];
1
+ function parseQuery(req) {
4
2
  const query = {};
3
+ const { url } = req;
4
+ const q = url.split("?")[1];
5
5
  if (q) {
6
- q.split("&").forEach((item) => {
7
- const [key, value] = item.split("=");
8
- query[key] = value;
6
+ const search = new URLSearchParams(q);
7
+ search.forEach((v, k) => {
8
+ query[k] = v;
9
9
  });
10
10
  }
11
11
  return query;
@@ -30,9 +30,21 @@ function getHost(request) {
30
30
  host = (host === null || host === void 0 ? void 0 : host.split(/\s*,\s*/, 1)[0]) || "undefined";
31
31
  return host;
32
32
  }
33
+ function parseCookie(req) {
34
+ const _cookie = req.headers.get("Cookie");
35
+ const cookie = {};
36
+ _cookie === null || _cookie === void 0 ? void 0 : _cookie.trim().split(";").forEach((item) => {
37
+ const [k, v] = item.trim().split("=");
38
+ if (k) {
39
+ cookie[k] = v;
40
+ }
41
+ });
42
+ return cookie;
43
+ }
33
44
  export {
34
45
  getHost,
35
46
  getPathname,
47
+ parseCookie,
36
48
  parseHeaders,
37
49
  parseQuery
38
50
  };
@@ -1,13 +1,15 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { Server as NodeServer } from 'node:http';
4
+ import type { Server as NodeHttpsServer } from 'node:https';
3
5
  import { NodeRequest, NodeResponse } from '../../../core/plugin';
4
6
  import { RequestHandler } from '../../../core/server';
5
7
  export declare const createWebRequest: (req: NodeRequest, res: NodeResponse) => Request;
6
8
  export declare const sendResponse: (response: Response, res: NodeResponse) => Promise<void>;
7
9
  declare const getRequestListener: (handler: RequestHandler) => (req: NodeRequest, res: NodeResponse) => Promise<void>;
8
- type NodeServerWrapper = NodeServer & {
10
+ type NodeServerWrapper = (NodeServer | NodeHttpsServer) & {
9
11
  getRequestListener: () => ReturnType<typeof getRequestListener>;
10
12
  getRequestHandler: () => RequestHandler;
11
13
  };
12
- export declare const createNodeServer: (requestHandler: RequestHandler) => NodeServerWrapper;
14
+ export declare const createNodeServer: (requestHandler: RequestHandler, httpsOptions?: Record<string, unknown>) => Promise<NodeServerWrapper>;
13
15
  export {};
@@ -1,6 +1,6 @@
1
1
  export { createErrorHtml, onError, ErrorDigest } from './utils';
2
2
  export { AGGRED_DIR } from './constants';
3
- export { favionFallbackMiddleware, injectReporter, injectLogger, getRenderHandler, bindRenderHandler, logHandler, processedBy, } from './middlewares';
3
+ export { favionFallbackMiddleware, injectReporter, injectLogger, getRenderHandler, bindRenderHandler, logHandler, processedBy, getLoaderCtx, } from './middlewares';
4
4
  export type { BindRenderHandleOptions } from './middlewares';
5
5
  export type { ServerBase, ServerBaseOptions } from './serverBase';
6
6
  export { createServerBase } from './serverBase';
@@ -1,3 +1,7 @@
1
1
  import { HookContext } from '@modern-js/types';
2
2
  import type { Context, ServerEnv } from '../../../core/server';
3
- export declare function createBaseHookContext(c: Context<ServerEnv>): HookContext;
3
+ export type ResArgs = {
4
+ status?: number;
5
+ headers: Headers;
6
+ };
7
+ export declare function createBaseHookContext(c: Context<ServerEnv>, resParams?: ResArgs): HookContext;
@@ -1,7 +1,8 @@
1
1
  import { AfterMatchContext, AfterRenderContext, MiddlewareContext, AfterStreamingRenderContext, ServerRoute, HookContext } from '@modern-js/types';
2
2
  import { Context, ServerEnv } from '../../../core/server';
3
3
  import type { ServerNodeEnv } from '../../adapters/node/hono';
4
+ import { ResArgs } from './base';
4
5
  export declare function getAfterMatchCtx(entryName: string, baseHookCtx: HookContext): AfterMatchContext;
5
6
  export declare function getAfterRenderCtx(c: Context, baseHookCtx: HookContext, route: Partial<ServerRoute>): Promise<AfterRenderContext>;
6
- export declare function createCustomMiddlewaresCtx(c: Context<ServerNodeEnv & ServerEnv>, locals: Record<string, any>): MiddlewareContext;
7
+ export declare function createCustomMiddlewaresCtx(c: Context<ServerNodeEnv & ServerEnv>, locals: Record<string, any>, resArgs?: ResArgs): MiddlewareContext;
7
8
  export declare function createAfterStreamingRenderContext(baseHookCtx: HookContext, route: Partial<ServerRoute>): (chunk: string) => AfterStreamingRenderContext;
@@ -3,11 +3,12 @@ import { ServerBase } from '../../serverBase';
3
3
  import { ServerHookRunner } from '../../../core/plugin';
4
4
  import { Middleware, ServerEnv } from '../../../core/server';
5
5
  import type { ServerNodeEnv } from '../../adapters/node/hono';
6
+ export { getLoaderCtx } from './loader';
6
7
  export declare class CustomServer {
7
8
  private runner;
8
9
  private serverMiddlewarePromise;
9
10
  private serverBase;
10
11
  constructor(runner: ServerHookRunner, serverBase: ServerBase, pwd: string);
11
12
  getHookMiddleware(entryName: string, routes: ServerRoute[]): Middleware<ServerEnv>;
12
- getServerMiddleware(): Middleware<ServerNodeEnv & ServerEnv>;
13
+ getServerMiddleware(): Promise<Middleware<ServerNodeEnv & ServerEnv> | Array<Middleware<ServerNodeEnv & ServerEnv>> | undefined>;
13
14
  }
@@ -0,0 +1,10 @@
1
+ import type { Context } from '../../../core/server';
2
+ type LoaderContext = Map<string, unknown>;
3
+ type Var = {
4
+ loaderContext: LoaderContext;
5
+ };
6
+ interface Env {
7
+ Variables: Var;
8
+ }
9
+ export declare function getLoaderCtx(c: Context<Env>): LoaderContext;
10
+ export {};
@@ -3,3 +3,4 @@ export * from './monitor';
3
3
  export * from './renderHandler';
4
4
  export * from './logger';
5
5
  export * from './frameworkHeader';
6
+ export { getLoaderCtx } from './customServer';
@@ -11,6 +11,7 @@ export interface SSRRenderOptions {
11
11
  metaName: string;
12
12
  logger: Logger;
13
13
  serverManifest: ServerManifest;
14
+ loaderContext: Map<string, unknown>;
14
15
  params: Params;
15
16
  /** Produce by custom server hook */
16
17
  locals?: Record<string, any>;
@@ -19,5 +20,5 @@ export interface SSRRenderOptions {
19
20
  nodeReq?: IncomingMessage;
20
21
  nonce?: string;
21
22
  }
22
- export declare function ssrRender(request: Request, { routeInfo, html, staticGenerate, nonce, metaName, reporter, logger, nodeReq, serverManifest, locals, params, metrics, }: SSRRenderOptions): Promise<Response>;
23
+ export declare function ssrRender(request: Request, { routeInfo, html, staticGenerate, nonce, metaName, reporter, logger, nodeReq, serverManifest, locals, params, metrics, loaderContext, }: SSRRenderOptions): Promise<Response>;
23
24
  export declare function getPathnameFromNodeReq(nodeReq: IncomingMessage): string;
@@ -1,7 +1,7 @@
1
1
  export * from './env';
2
- export * from './request';
3
2
  export * from './transformStream';
4
3
  export * from './middlewareCollector';
5
4
  export * from './error';
6
5
  export * from './warmup';
7
6
  export * from './entry';
7
+ export * from './request';
@@ -1,5 +1,7 @@
1
- export declare function parseQuery(request: Request): Record<string, string>;
2
- export declare function parseHeaders(request: Request): Record<string, string | undefined>;
1
+ export type Query = Record<string, string>;
2
+ export declare function parseQuery(req: Request): Query;
3
+ export type HeadersData = Record<string, string | undefined>;
4
+ export declare function parseHeaders(request: Request): HeadersData;
3
5
  /**
4
6
  * The function is modified based on
5
7
  * https://github.com/honojs/hono/blob/main/src/utils/url.ts
@@ -10,3 +12,6 @@ export declare function parseHeaders(request: Request): Record<string, string |
10
12
  */
11
13
  export declare function getPathname(request: Request): string;
12
14
  export declare function getHost(request: Request): string;
15
+ type Cookie = Record<string, string>;
16
+ export declare function parseCookie(req: Request): Cookie;
17
+ export {};