@modern-js/prod-server 2.42.2 → 2.43.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 (82) hide show
  1. package/dist/cjs/libs/render/index.js +3 -11
  2. package/dist/cjs/libs/render/ssr.js +2 -2
  3. package/dist/cjs/libs/render/{cache/page-caches/lru.js → ssrCache/cacheMod.js} +21 -31
  4. package/dist/cjs/libs/render/ssrCache/index.js +81 -0
  5. package/dist/cjs/libs/render/ssrCache/manager.js +104 -0
  6. package/dist/cjs/libs/render/static.js +5 -5
  7. package/dist/cjs/server/index.js +2 -0
  8. package/dist/cjs/server/modernServer.js +2 -9
  9. package/dist/esm/libs/render/index.js +3 -11
  10. package/dist/esm/libs/render/ssr.js +2 -2
  11. package/dist/esm/libs/render/ssrCache/cacheMod.js +33 -0
  12. package/dist/esm/libs/render/ssrCache/index.js +146 -0
  13. package/dist/esm/libs/render/ssrCache/manager.js +159 -0
  14. package/dist/esm/libs/render/static.js +5 -5
  15. package/dist/esm/server/index.js +14 -4
  16. package/dist/esm/server/modernServer.js +32 -42
  17. package/dist/esm-node/libs/render/index.js +3 -11
  18. package/dist/esm-node/libs/render/ssr.js +2 -2
  19. package/dist/esm-node/libs/render/ssrCache/cacheMod.js +22 -0
  20. package/dist/esm-node/libs/render/ssrCache/index.js +57 -0
  21. package/dist/esm-node/libs/render/ssrCache/manager.js +80 -0
  22. package/dist/esm-node/libs/render/static.js +5 -5
  23. package/dist/esm-node/server/index.js +2 -0
  24. package/dist/esm-node/server/modernServer.js +2 -9
  25. package/dist/types/libs/context/index.d.ts +2 -0
  26. package/dist/types/libs/preload/flushServerHeader.d.ts +2 -0
  27. package/dist/types/libs/proxy.d.ts +2 -0
  28. package/dist/types/libs/render/ssrCache/cacheMod.d.ts +8 -0
  29. package/dist/types/libs/render/ssrCache/index.d.ts +7 -0
  30. package/dist/types/libs/render/ssrCache/manager.d.ts +14 -0
  31. package/dist/types/renderHtml.d.ts +2 -0
  32. package/dist/types/server/index.d.ts +2 -0
  33. package/dist/types/server/modernServer.d.ts +2 -3
  34. package/dist/types/type.d.ts +2 -0
  35. package/package.json +8 -11
  36. package/dist/cjs/libs/render/cache/__tests__/cache.fun.test.js +0 -95
  37. package/dist/cjs/libs/render/cache/__tests__/cache.test.js +0 -223
  38. package/dist/cjs/libs/render/cache/__tests__/cacheable.js +0 -93
  39. package/dist/cjs/libs/render/cache/__tests__/error-configuration.js +0 -71
  40. package/dist/cjs/libs/render/cache/__tests__/matched-cache.js +0 -173
  41. package/dist/cjs/libs/render/cache/index.js +0 -92
  42. package/dist/cjs/libs/render/cache/page-caches/index.js +0 -36
  43. package/dist/cjs/libs/render/cache/spr.js +0 -247
  44. package/dist/cjs/libs/render/cache/type.js +0 -16
  45. package/dist/cjs/libs/render/cache/util.js +0 -121
  46. package/dist/cjs/libs/render/reader.js +0 -131
  47. package/dist/esm/libs/render/cache/__tests__/cache.fun.test.js +0 -124
  48. package/dist/esm/libs/render/cache/__tests__/cache.test.js +0 -612
  49. package/dist/esm/libs/render/cache/__tests__/cacheable.js +0 -69
  50. package/dist/esm/libs/render/cache/__tests__/error-configuration.js +0 -47
  51. package/dist/esm/libs/render/cache/__tests__/matched-cache.js +0 -149
  52. package/dist/esm/libs/render/cache/index.js +0 -204
  53. package/dist/esm/libs/render/cache/page-caches/index.js +0 -34
  54. package/dist/esm/libs/render/cache/page-caches/lru.js +0 -57
  55. package/dist/esm/libs/render/cache/spr.js +0 -345
  56. package/dist/esm/libs/render/cache/type.js +0 -0
  57. package/dist/esm/libs/render/cache/util.js +0 -105
  58. package/dist/esm/libs/render/reader.js +0 -196
  59. package/dist/esm-node/libs/render/cache/__tests__/cache.fun.test.js +0 -72
  60. package/dist/esm-node/libs/render/cache/__tests__/cache.test.js +0 -222
  61. package/dist/esm-node/libs/render/cache/__tests__/cacheable.js +0 -69
  62. package/dist/esm-node/libs/render/cache/__tests__/error-configuration.js +0 -47
  63. package/dist/esm-node/libs/render/cache/__tests__/matched-cache.js +0 -149
  64. package/dist/esm-node/libs/render/cache/index.js +0 -72
  65. package/dist/esm-node/libs/render/cache/page-caches/index.js +0 -12
  66. package/dist/esm-node/libs/render/cache/page-caches/lru.js +0 -32
  67. package/dist/esm-node/libs/render/cache/spr.js +0 -212
  68. package/dist/esm-node/libs/render/cache/type.js +0 -0
  69. package/dist/esm-node/libs/render/cache/util.js +0 -80
  70. package/dist/esm-node/libs/render/reader.js +0 -93
  71. package/dist/types/libs/render/cache/__tests__/cache.fun.test.d.ts +0 -1
  72. package/dist/types/libs/render/cache/__tests__/cache.test.d.ts +0 -1
  73. package/dist/types/libs/render/cache/__tests__/cacheable.d.ts +0 -62
  74. package/dist/types/libs/render/cache/__tests__/error-configuration.d.ts +0 -28
  75. package/dist/types/libs/render/cache/__tests__/matched-cache.d.ts +0 -124
  76. package/dist/types/libs/render/cache/index.d.ts +0 -6
  77. package/dist/types/libs/render/cache/page-caches/index.d.ts +0 -2
  78. package/dist/types/libs/render/cache/page-caches/lru.d.ts +0 -15
  79. package/dist/types/libs/render/cache/spr.d.ts +0 -22
  80. package/dist/types/libs/render/cache/type.d.ts +0 -48
  81. package/dist/types/libs/render/cache/util.d.ts +0 -18
  82. package/dist/types/libs/render/reader.d.ts +0 -20
@@ -0,0 +1,159 @@
1
+ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
+ import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
3
+ import { _ as _create_class } from "@swc/helpers/_/_create_class";
4
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
5
+ import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
6
+ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
7
+ import { Transform } from "stream";
8
+ var CacheManager = /* @__PURE__ */ function() {
9
+ "use strict";
10
+ function CacheManager2(containter) {
11
+ _class_call_check(this, CacheManager2);
12
+ _define_property(this, "containter", void 0);
13
+ this.containter = containter;
14
+ }
15
+ _create_class(CacheManager2, [
16
+ {
17
+ key: "getCacheResult",
18
+ value: function getCacheResult(req, cacheControl, render, ssrContext) {
19
+ var _this = this;
20
+ return _async_to_generator(function() {
21
+ var key, value, maxAge, staleWhileRevalidate, ttl, cache, interval;
22
+ return _ts_generator(this, function(_state) {
23
+ switch (_state.label) {
24
+ case 0:
25
+ key = _this.computedKey(req, cacheControl);
26
+ return [
27
+ 4,
28
+ _this.containter.get(key)
29
+ ];
30
+ case 1:
31
+ value = _state.sent();
32
+ maxAge = cacheControl.maxAge, staleWhileRevalidate = cacheControl.staleWhileRevalidate;
33
+ ttl = maxAge + staleWhileRevalidate;
34
+ if (value) {
35
+ cache = JSON.parse(value);
36
+ interval = Date.now() - cache.cursor;
37
+ if (interval <= maxAge) {
38
+ return [
39
+ 2,
40
+ cache.val
41
+ ];
42
+ } else if (interval <= staleWhileRevalidate + maxAge) {
43
+ _this.processCache(key, render, ssrContext, ttl);
44
+ return [
45
+ 2,
46
+ cache.val
47
+ ];
48
+ } else {
49
+ return [
50
+ 2,
51
+ _this.processCache(key, render, ssrContext, ttl)
52
+ ];
53
+ }
54
+ } else {
55
+ return [
56
+ 2,
57
+ _this.processCache(key, render, ssrContext, ttl)
58
+ ];
59
+ }
60
+ return [
61
+ 2
62
+ ];
63
+ }
64
+ });
65
+ })();
66
+ }
67
+ },
68
+ {
69
+ key: "processCache",
70
+ value: function processCache(key, render, ssrContext, ttl) {
71
+ var _this = this;
72
+ return _async_to_generator(function() {
73
+ var renderResult, current, cache, html, stream;
74
+ return _ts_generator(this, function(_state) {
75
+ switch (_state.label) {
76
+ case 0:
77
+ return [
78
+ 4,
79
+ render(ssrContext)
80
+ ];
81
+ case 1:
82
+ renderResult = _state.sent();
83
+ if (!(typeof renderResult === "string"))
84
+ return [
85
+ 3,
86
+ 3
87
+ ];
88
+ current = Date.now();
89
+ cache = {
90
+ val: renderResult,
91
+ cursor: current
92
+ };
93
+ return [
94
+ 4,
95
+ _this.containter.set(key, JSON.stringify(cache), {
96
+ ttl
97
+ })
98
+ ];
99
+ case 2:
100
+ _state.sent();
101
+ return [
102
+ 2,
103
+ renderResult
104
+ ];
105
+ case 3:
106
+ stream = new Transform({
107
+ write: function write(chunk, _, callback) {
108
+ html += chunk.toString();
109
+ this.push(chunk);
110
+ callback();
111
+ }
112
+ });
113
+ stream.on("close", function() {
114
+ var current2 = Date.now();
115
+ var cache2 = {
116
+ val: html,
117
+ cursor: current2
118
+ };
119
+ _this.containter.set(key, JSON.stringify(cache2), {
120
+ ttl
121
+ });
122
+ });
123
+ return [
124
+ 2,
125
+ renderResult(stream)
126
+ ];
127
+ case 4:
128
+ return [
129
+ 2
130
+ ];
131
+ }
132
+ });
133
+ })();
134
+ }
135
+ },
136
+ {
137
+ key: "computedKey",
138
+ value: function computedKey(req, cacheControl) {
139
+ var url = req.url;
140
+ var _url_split = _sliced_to_array(url.split("?"), 1), pathname = _url_split[0];
141
+ var customKey = cacheControl.customKey;
142
+ var defaultKey = pathname.replace(/.+\/+$/, "");
143
+ if (customKey) {
144
+ if (typeof customKey === "string") {
145
+ return customKey;
146
+ } else {
147
+ return customKey(defaultKey);
148
+ }
149
+ } else {
150
+ return defaultKey;
151
+ }
152
+ }
153
+ }
154
+ ]);
155
+ return CacheManager2;
156
+ }();
157
+ export {
158
+ CacheManager
159
+ };
@@ -2,7 +2,7 @@ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
2
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
3
3
  import path from "path";
4
4
  import { mime } from "@modern-js/utils";
5
- import { readFile } from "./reader";
5
+ import { fileReader } from "@modern-js/runtime-utils/fileReader";
6
6
  function handleDirectory(ctx, entryPath, urlPath) {
7
7
  return _handleDirectory.apply(this, arguments);
8
8
  }
@@ -16,7 +16,7 @@ function _handleDirectory() {
16
16
  filepath = path.join(entryPath, trimLeft(pathname, urlPath));
17
17
  return [
18
18
  4,
19
- readFile(filepath)
19
+ fileReader.readFile(filepath)
20
20
  ];
21
21
  case 1:
22
22
  content = _state.sent();
@@ -33,7 +33,7 @@ function _handleDirectory() {
33
33
  ];
34
34
  return [
35
35
  4,
36
- readFile("".concat(filepath, "index.html"))
36
+ fileReader.readFile("".concat(filepath, "index.html"))
37
37
  ];
38
38
  case 2:
39
39
  content = _state.sent();
@@ -49,7 +49,7 @@ function _handleDirectory() {
49
49
  ];
50
50
  return [
51
51
  4,
52
- readFile("".concat(filepath, ".html"))
52
+ fileReader.readFile("".concat(filepath, ".html"))
53
53
  ];
54
54
  case 4:
55
55
  content = _state.sent();
@@ -60,7 +60,7 @@ function _handleDirectory() {
60
60
  ];
61
61
  return [
62
62
  4,
63
- readFile("".concat(filepath, "/index.html"))
63
+ fileReader.readFile("".concat(filepath, "/index.html"))
64
64
  ];
65
65
  case 5:
66
66
  content = _state.sent();
@@ -217,11 +217,21 @@ var Server = /* @__PURE__ */ function() {
217
217
  value: function close() {
218
218
  var _this = this;
219
219
  return _async_to_generator(function() {
220
+ var _this_server_close, _this_server;
220
221
  return _ts_generator(this, function(_state) {
221
- _this.app.close();
222
- return [
223
- 2
224
- ];
222
+ switch (_state.label) {
223
+ case 0:
224
+ return [
225
+ 4,
226
+ (_this_server_close = (_this_server = _this.server).close) === null || _this_server_close === void 0 ? void 0 : _this_server_close.call(_this_server)
227
+ ];
228
+ case 1:
229
+ _state.sent();
230
+ _this.app.close();
231
+ return [
232
+ 2
233
+ ];
234
+ }
225
235
  });
226
236
  })();
227
237
  }
@@ -13,11 +13,11 @@ import { RouteMatchManager } from "../libs/route";
13
13
  import { createRenderHandler } from "../libs/render";
14
14
  import { createStaticFileHandler, faviconFallbackHandler } from "../libs/serveFile";
15
15
  import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect } from "../utils";
16
- import * as reader from "../libs/render/reader";
17
16
  import { createProxyHandler } from "../libs/proxy";
18
17
  import { createContext } from "../libs/context";
19
18
  import { AGGRED_DIR, ERROR_DIGEST, ERROR_PAGE_TEXT, RUN_MODE, ServerReportTimings } from "../constants";
20
19
  import { createAfterMatchContext, createAfterRenderContext, createMiddlewareContext } from "../libs/hook-api";
20
+ import { cacheMod } from "../libs/render/ssrCache/cacheMod";
21
21
  var SERVER_DIR = "./server";
22
22
  var ModernServer = /* @__PURE__ */ function() {
23
23
  "use strict";
@@ -35,7 +35,6 @@ var ModernServer = /* @__PURE__ */ function() {
35
35
  _define_property(this, "logger", void 0);
36
36
  _define_property(this, "metrics", void 0);
37
37
  _define_property(this, "runMode", void 0);
38
- _define_property(this, "reader", reader);
39
38
  _define_property(this, "proxyTarget", void 0);
40
39
  _define_property(this, "routeRenderHandler", void 0);
41
40
  _define_property(this, "staticGenerate", void 0);
@@ -73,7 +72,6 @@ var ModernServer = /* @__PURE__ */ function() {
73
72
  case 0:
74
73
  _this.runner = runner;
75
74
  distDir = _this.distDir, conf = _this.conf;
76
- _this.initReader();
77
75
  debug("final server conf", _this.conf);
78
76
  if ((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy) {
79
77
  _createProxyHandler = createProxyHandler(conf.bff.proxy), handlers = _createProxyHandler.handlers, handleUpgrade = _createProxyHandler.handleUpgrade;
@@ -82,12 +80,10 @@ var ModernServer = /* @__PURE__ */ function() {
82
80
  _this.addHandler(handler);
83
81
  });
84
82
  }
85
- app === null || app === void 0 ? void 0 : app.on("close", function() {
86
- _this.reader.close();
87
- });
88
83
  usageRoutes = _this.filterRoutes(_this.getRoutes());
89
84
  _this.router.reset(usageRoutes);
90
85
  _this.warmupSSRBundle();
86
+ cacheMod.loadServerCacheMod(_this.pwd);
91
87
  return [
92
88
  4,
93
89
  _this.prepareFrameHandler()
@@ -218,47 +214,41 @@ var ModernServer = /* @__PURE__ */ function() {
218
214
  }
219
215
  },
220
216
  {
221
- key: "initReader",
217
+ key: "onServerChange",
222
218
  value: (
223
219
  /* —————————————————————— function will be overwrite —————————————————————— */
224
- function initReader() {
225
- this.reader.init();
220
+ function onServerChange(param) {
221
+ var filepath = param.filepath;
222
+ var _this = this;
223
+ return _async_to_generator(function() {
224
+ var pwd, api, server, apiPath, serverPath, onlyApi, onlyWeb;
225
+ return _ts_generator(this, function(_state) {
226
+ switch (_state.label) {
227
+ case 0:
228
+ pwd = _this.pwd;
229
+ api = AGGRED_DIR.api, server = AGGRED_DIR.server;
230
+ apiPath = path.normalize(path.join(pwd, api));
231
+ serverPath = path.normalize(path.join(pwd, server));
232
+ onlyApi = filepath.startsWith(apiPath);
233
+ onlyWeb = filepath.startsWith(serverPath);
234
+ return [
235
+ 4,
236
+ _this.prepareFrameHandler({
237
+ onlyWeb,
238
+ onlyApi
239
+ })
240
+ ];
241
+ case 1:
242
+ _state.sent();
243
+ return [
244
+ 2
245
+ ];
246
+ }
247
+ });
248
+ })();
226
249
  }
227
250
  )
228
251
  },
229
- {
230
- key: "onServerChange",
231
- value: function onServerChange(param) {
232
- var filepath = param.filepath;
233
- var _this = this;
234
- return _async_to_generator(function() {
235
- var pwd, api, server, apiPath, serverPath, onlyApi, onlyWeb;
236
- return _ts_generator(this, function(_state) {
237
- switch (_state.label) {
238
- case 0:
239
- pwd = _this.pwd;
240
- api = AGGRED_DIR.api, server = AGGRED_DIR.server;
241
- apiPath = path.normalize(path.join(pwd, api));
242
- serverPath = path.normalize(path.join(pwd, server));
243
- onlyApi = filepath.startsWith(apiPath);
244
- onlyWeb = filepath.startsWith(serverPath);
245
- return [
246
- 4,
247
- _this.prepareFrameHandler({
248
- onlyWeb,
249
- onlyApi
250
- })
251
- ];
252
- case 1:
253
- _state.sent();
254
- return [
255
- 2
256
- ];
257
- }
258
- });
259
- })();
260
- }
261
- },
262
252
  {
263
253
  key: "getRoutes",
264
254
  value: (
@@ -1,9 +1,9 @@
1
1
  import path from "path";
2
2
  import { cutNameByHyphen, mime } from "@modern-js/utils";
3
+ import { fileReader } from "@modern-js/runtime-utils/fileReader";
3
4
  import { ERROR_DIGEST } from "../../constants";
4
5
  import { shouldFlushServerHeader } from "../preload/shouldFlushServerHeader";
5
6
  import { handleDirectory } from "./static";
6
- import { readFile } from "./reader";
7
7
  import * as ssr from "./ssr";
8
8
  import { injectServerData } from "./utils";
9
9
  const calcFallback = (metaName) => `x-${cutNameByHyphen(metaName)}-ssr-fallback`;
@@ -18,7 +18,7 @@ const createRenderHandler = ({ distDir, staticGenerate, conf, forceCSR, nonce, s
18
18
  return result;
19
19
  }
20
20
  const templatePath = entry;
21
- const content = await readFile(templatePath);
21
+ const content = await fileReader.readFile(templatePath);
22
22
  if (!content) {
23
23
  return null;
24
24
  }
@@ -48,15 +48,7 @@ const createRenderHandler = ({ distDir, staticGenerate, conf, forceCSR, nonce, s
48
48
  staticGenerate,
49
49
  nonce
50
50
  };
51
- const result = await (ssrRender ? ssrRender(ctx, ssrRenderOptions, runner) : ssr.render(ctx, {
52
- distDir,
53
- entryName: route.entryName,
54
- urlPath: route.urlPath,
55
- bundle: route.bundle,
56
- template: content.toString(),
57
- staticGenerate,
58
- nonce
59
- }, runner));
51
+ const result = await (ssrRender ? ssrRender(ctx, ssrRenderOptions, runner) : ssr.render(ctx, ssrRenderOptions, runner));
60
52
  return result;
61
53
  } catch (err) {
62
54
  ctx.error(ERROR_DIGEST.ERENDER, err.stack || err.message);
@@ -1,8 +1,8 @@
1
1
  import path from "path";
2
2
  import { fs, mime, LOADABLE_STATS_FILE, ROUTE_MANIFEST_FILE, SERVER_RENDER_FUNCTION_NAME } from "@modern-js/utils";
3
- import cache from "./cache";
4
3
  import { createLogger, createMetrics } from "./measure";
5
4
  import { injectServerDataStream, injectServerData } from "./utils";
5
+ import { ssrCache } from "./ssrCache";
6
6
  const render = async (ctx, renderOptions, runner) => {
7
7
  var _ctx_res;
8
8
  const { urlPath, bundle, distDir, template, entryName, staticGenerate, enableUnsafeCtx = false, nonce } = renderOptions;
@@ -50,7 +50,7 @@ const render = async (ctx, renderOptions, runner) => {
50
50
  runner.extendSSRContext(context);
51
51
  const bundleJSContent = await Promise.resolve(require(bundleJS));
52
52
  const serverRender = bundleJSContent[SERVER_RENDER_FUNCTION_NAME];
53
- const content = await cache(serverRender, ctx)(context);
53
+ const content = await ssrCache(ctx.req, serverRender, context);
54
54
  const { url, status = 302 } = context.redirection;
55
55
  if (url) {
56
56
  return {
@@ -0,0 +1,22 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
+ import path from "path";
3
+ import { SERVER_DIR, requireExistModule } from "@modern-js/utils";
4
+ const CACHE_FILENAME = "cache";
5
+ class ServerCacheMod {
6
+ loadServerCacheMod(pwd = process.cwd()) {
7
+ const serverCacheFilepath = path.resolve(pwd, SERVER_DIR, CACHE_FILENAME);
8
+ const mod = requireExistModule(serverCacheFilepath, {
9
+ interop: false
10
+ });
11
+ this.customContainer = mod === null || mod === void 0 ? void 0 : mod.customContainer;
12
+ this.cacheOption = mod === null || mod === void 0 ? void 0 : mod.cacheOption;
13
+ }
14
+ constructor() {
15
+ _define_property(this, "customContainer", void 0);
16
+ _define_property(this, "cacheOption", void 0);
17
+ }
18
+ }
19
+ const cacheMod = new ServerCacheMod();
20
+ export {
21
+ cacheMod
22
+ };
@@ -0,0 +1,57 @@
1
+ import { Transform } from "stream";
2
+ import { createMemoryStorage } from "@modern-js/runtime-utils/storer";
3
+ import { cacheMod } from "./cacheMod";
4
+ import { CacheManager } from "./manager";
5
+ const cacheStorage = createMemoryStorage("__ssr__cache");
6
+ async function ssrCache(req, render, ssrContext) {
7
+ const { customContainer, cacheOption } = cacheMod;
8
+ const cacheControl = await matchCacheControl(req, cacheOption);
9
+ const cacheManager = new CacheManager(customContainer ? customContainer : cacheStorage);
10
+ if (cacheControl) {
11
+ return cacheManager.getCacheResult(req, cacheControl, render, ssrContext);
12
+ } else {
13
+ const renderResult = await render(ssrContext);
14
+ if (typeof renderResult === "string") {
15
+ return renderResult;
16
+ } else {
17
+ const stream = new Transform({
18
+ write(chunk, _, callback) {
19
+ this.push(chunk);
20
+ callback();
21
+ }
22
+ });
23
+ return renderResult(stream);
24
+ }
25
+ }
26
+ }
27
+ async function matchCacheControl(req, cacheOption) {
28
+ if (!cacheOption) {
29
+ return void 0;
30
+ } else if (isCacheControl(cacheOption)) {
31
+ return cacheOption;
32
+ } else if (isCacheOptionProvider(cacheOption)) {
33
+ return cacheOption(req);
34
+ } else {
35
+ const url = req.url;
36
+ const options = Object.entries(cacheOption);
37
+ for (const [key, option] of options) {
38
+ if (key === "*" || new RegExp(key).test(url)) {
39
+ if (typeof option === "function") {
40
+ return option(req);
41
+ } else {
42
+ return option;
43
+ }
44
+ }
45
+ }
46
+ return void 0;
47
+ }
48
+ function isCacheOptionProvider(option) {
49
+ return typeof option === "function";
50
+ }
51
+ function isCacheControl(option) {
52
+ return typeof option === "object" && option !== null && "maxAge" in option;
53
+ }
54
+ }
55
+ export {
56
+ ssrCache
57
+ };
@@ -0,0 +1,80 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
+ import { Transform } from "stream";
3
+ class CacheManager {
4
+ async getCacheResult(req, cacheControl, render, ssrContext) {
5
+ const key = this.computedKey(req, cacheControl);
6
+ const value = await this.containter.get(key);
7
+ const { maxAge, staleWhileRevalidate } = cacheControl;
8
+ const ttl = maxAge + staleWhileRevalidate;
9
+ if (value) {
10
+ const cache = JSON.parse(value);
11
+ const interval = Date.now() - cache.cursor;
12
+ if (interval <= maxAge) {
13
+ return cache.val;
14
+ } else if (interval <= staleWhileRevalidate + maxAge) {
15
+ this.processCache(key, render, ssrContext, ttl);
16
+ return cache.val;
17
+ } else {
18
+ return this.processCache(key, render, ssrContext, ttl);
19
+ }
20
+ } else {
21
+ return this.processCache(key, render, ssrContext, ttl);
22
+ }
23
+ }
24
+ async processCache(key, render, ssrContext, ttl) {
25
+ const renderResult = await render(ssrContext);
26
+ if (typeof renderResult === "string") {
27
+ const current = Date.now();
28
+ const cache = {
29
+ val: renderResult,
30
+ cursor: current
31
+ };
32
+ await this.containter.set(key, JSON.stringify(cache), {
33
+ ttl
34
+ });
35
+ return renderResult;
36
+ } else {
37
+ let html;
38
+ const stream = new Transform({
39
+ write(chunk, _, callback) {
40
+ html += chunk.toString();
41
+ this.push(chunk);
42
+ callback();
43
+ }
44
+ });
45
+ stream.on("close", () => {
46
+ const current = Date.now();
47
+ const cache = {
48
+ val: html,
49
+ cursor: current
50
+ };
51
+ this.containter.set(key, JSON.stringify(cache), {
52
+ ttl
53
+ });
54
+ });
55
+ return renderResult(stream);
56
+ }
57
+ }
58
+ computedKey(req, cacheControl) {
59
+ const { url } = req;
60
+ const [pathname] = url.split("?");
61
+ const { customKey } = cacheControl;
62
+ const defaultKey = pathname.replace(/.+\/+$/, "");
63
+ if (customKey) {
64
+ if (typeof customKey === "string") {
65
+ return customKey;
66
+ } else {
67
+ return customKey(defaultKey);
68
+ }
69
+ } else {
70
+ return defaultKey;
71
+ }
72
+ }
73
+ constructor(containter) {
74
+ _define_property(this, "containter", void 0);
75
+ this.containter = containter;
76
+ }
77
+ }
78
+ export {
79
+ CacheManager
80
+ };
@@ -1,18 +1,18 @@
1
1
  import path from "path";
2
2
  import { mime } from "@modern-js/utils";
3
- import { readFile } from "./reader";
3
+ import { fileReader } from "@modern-js/runtime-utils/fileReader";
4
4
  async function handleDirectory(ctx, entryPath, urlPath) {
5
5
  const { path: pathname } = ctx;
6
6
  const filepath = path.join(entryPath, trimLeft(pathname, urlPath));
7
- let content = await readFile(filepath);
7
+ let content = await fileReader.readFile(filepath);
8
8
  let contentType = mime.contentType(path.extname(filepath) || "");
9
9
  if (!content) {
10
10
  if (pathname.endsWith("/")) {
11
- content = await readFile(`${filepath}index.html`);
11
+ content = await fileReader.readFile(`${filepath}index.html`);
12
12
  } else if (!pathname.includes(".")) {
13
- content = await readFile(`${filepath}.html`);
13
+ content = await fileReader.readFile(`${filepath}.html`);
14
14
  if (!content) {
15
- content = await readFile(`${filepath}/index.html`);
15
+ content = await fileReader.readFile(`${filepath}/index.html`);
16
16
  }
17
17
  }
18
18
  if (content) {
@@ -88,6 +88,8 @@ class Server {
88
88
  });
89
89
  }
90
90
  async close() {
91
+ var _this_server_close, _this_server;
92
+ await ((_this_server_close = (_this_server = this.server).close) === null || _this_server_close === void 0 ? void 0 : _this_server_close.call(_this_server));
91
93
  this.app.close();
92
94
  }
93
95
  listen(options, listener) {
@@ -7,11 +7,11 @@ import { RouteMatchManager } from "../libs/route";
7
7
  import { createRenderHandler } from "../libs/render";
8
8
  import { createStaticFileHandler, faviconFallbackHandler } from "../libs/serveFile";
9
9
  import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect } from "../utils";
10
- import * as reader from "../libs/render/reader";
11
10
  import { createProxyHandler } from "../libs/proxy";
12
11
  import { createContext } from "../libs/context";
13
12
  import { AGGRED_DIR, ERROR_DIGEST, ERROR_PAGE_TEXT, RUN_MODE, ServerReportTimings } from "../constants";
14
13
  import { createAfterMatchContext, createAfterRenderContext, createMiddlewareContext } from "../libs/hook-api";
14
+ import { cacheMod } from "../libs/render/ssrCache/cacheMod";
15
15
  const SERVER_DIR = "./server";
16
16
  class ModernServer {
17
17
  // server prepare
@@ -19,7 +19,6 @@ class ModernServer {
19
19
  var _conf_bff, _this_conf_output;
20
20
  this.runner = runner;
21
21
  const { distDir, conf } = this;
22
- this.initReader();
23
22
  debug("final server conf", this.conf);
24
23
  if ((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy) {
25
24
  const { handlers, handleUpgrade } = createProxyHandler(conf.bff.proxy);
@@ -28,12 +27,10 @@ class ModernServer {
28
27
  this.addHandler(handler);
29
28
  });
30
29
  }
31
- app === null || app === void 0 ? void 0 : app.on("close", () => {
32
- this.reader.close();
33
- });
34
30
  const usageRoutes = this.filterRoutes(this.getRoutes());
35
31
  this.router.reset(usageRoutes);
36
32
  this.warmupSSRBundle();
33
+ cacheMod.loadServerCacheMod(this.pwd);
37
34
  await this.prepareFrameHandler();
38
35
  await this.prepareLoaderHandler(usageRoutes, distDir);
39
36
  this.routeRenderHandler = this.getRenderHandler();
@@ -89,9 +86,6 @@ class ModernServer {
89
86
  return createServer(handler);
90
87
  }
91
88
  /* —————————————————————— function will be overwrite —————————————————————— */
92
- initReader() {
93
- this.reader.init();
94
- }
95
89
  async onServerChange({ filepath }) {
96
90
  const { pwd } = this;
97
91
  const { api, server } = AGGRED_DIR;
@@ -475,7 +469,6 @@ class ModernServer {
475
469
  _define_property(this, "logger", void 0);
476
470
  _define_property(this, "metrics", void 0);
477
471
  _define_property(this, "runMode", void 0);
478
- _define_property(this, "reader", reader);
479
472
  _define_property(this, "proxyTarget", void 0);
480
473
  _define_property(this, "routeRenderHandler", void 0);
481
474
  _define_property(this, "staticGenerate", void 0);
@@ -1,3 +1,5 @@
1
+ /// <reference path="../../type.d.ts" />
2
+ /// <reference types="node/http" />
1
3
  import { IncomingMessage, ServerResponse } from 'http';
2
4
  import { ModernServerContext, ContextOptions } from './context';
3
5
  export declare const createContext: (req: IncomingMessage, res: ServerResponse, options?: ContextOptions) => ModernServerContext;
@@ -1,4 +1,6 @@
1
+ /// <reference path="../../type.d.ts" />
1
2
  /// <reference types="node" />
3
+ /// <reference types="node/http" />
2
4
  import { OutgoingHttpHeaders } from 'http';
3
5
  import { ServerOptions } from '@modern-js/server-core';
4
6
  import { ModernServerContext } from '@modern-js/types';
@@ -1,3 +1,5 @@
1
+ /// <reference path="../type.d.ts" />
2
+ /// <reference types="node/http" />
1
3
  import http from 'http';
2
4
  import { RequestHandler } from 'http-proxy-middleware';
3
5
  import { ProxyDetail, BffProxyOptions } from '@modern-js/types';