@modern-js/prod-server 2.42.2-alpha.0 → 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.
- package/dist/cjs/libs/render/index.js +3 -11
- package/dist/cjs/libs/render/ssr.js +2 -2
- package/dist/cjs/libs/render/{cache/page-caches/lru.js → ssrCache/cacheMod.js} +21 -31
- package/dist/cjs/libs/render/ssrCache/index.js +81 -0
- package/dist/cjs/libs/render/ssrCache/manager.js +104 -0
- package/dist/cjs/libs/render/static.js +5 -5
- package/dist/cjs/server/index.js +2 -0
- package/dist/cjs/server/modernServer.js +2 -9
- package/dist/esm/libs/render/index.js +3 -11
- package/dist/esm/libs/render/ssr.js +2 -2
- package/dist/esm/libs/render/ssrCache/cacheMod.js +33 -0
- package/dist/esm/libs/render/ssrCache/index.js +146 -0
- package/dist/esm/libs/render/ssrCache/manager.js +159 -0
- package/dist/esm/libs/render/static.js +5 -5
- package/dist/esm/server/index.js +14 -4
- package/dist/esm/server/modernServer.js +32 -42
- package/dist/esm-node/libs/render/index.js +3 -11
- package/dist/esm-node/libs/render/ssr.js +2 -2
- package/dist/esm-node/libs/render/ssrCache/cacheMod.js +22 -0
- package/dist/esm-node/libs/render/ssrCache/index.js +57 -0
- package/dist/esm-node/libs/render/ssrCache/manager.js +80 -0
- package/dist/esm-node/libs/render/static.js +5 -5
- package/dist/esm-node/server/index.js +2 -0
- package/dist/esm-node/server/modernServer.js +2 -9
- package/dist/types/libs/context/index.d.ts +2 -0
- package/dist/types/libs/preload/flushServerHeader.d.ts +2 -0
- package/dist/types/libs/proxy.d.ts +2 -0
- package/dist/types/libs/render/ssrCache/cacheMod.d.ts +8 -0
- package/dist/types/libs/render/ssrCache/index.d.ts +7 -0
- package/dist/types/libs/render/ssrCache/manager.d.ts +14 -0
- package/dist/types/renderHtml.d.ts +2 -0
- package/dist/types/server/index.d.ts +2 -0
- package/dist/types/server/modernServer.d.ts +2 -3
- package/dist/types/type.d.ts +2 -0
- package/package.json +8 -11
- package/dist/cjs/libs/render/cache/__tests__/cache.fun.test.js +0 -95
- package/dist/cjs/libs/render/cache/__tests__/cache.test.js +0 -223
- package/dist/cjs/libs/render/cache/__tests__/cacheable.js +0 -93
- package/dist/cjs/libs/render/cache/__tests__/error-configuration.js +0 -71
- package/dist/cjs/libs/render/cache/__tests__/matched-cache.js +0 -173
- package/dist/cjs/libs/render/cache/index.js +0 -92
- package/dist/cjs/libs/render/cache/page-caches/index.js +0 -36
- package/dist/cjs/libs/render/cache/spr.js +0 -247
- package/dist/cjs/libs/render/cache/type.js +0 -16
- package/dist/cjs/libs/render/cache/util.js +0 -121
- package/dist/cjs/libs/render/reader.js +0 -131
- package/dist/esm/libs/render/cache/__tests__/cache.fun.test.js +0 -124
- package/dist/esm/libs/render/cache/__tests__/cache.test.js +0 -612
- package/dist/esm/libs/render/cache/__tests__/cacheable.js +0 -69
- package/dist/esm/libs/render/cache/__tests__/error-configuration.js +0 -47
- package/dist/esm/libs/render/cache/__tests__/matched-cache.js +0 -149
- package/dist/esm/libs/render/cache/index.js +0 -204
- package/dist/esm/libs/render/cache/page-caches/index.js +0 -34
- package/dist/esm/libs/render/cache/page-caches/lru.js +0 -57
- package/dist/esm/libs/render/cache/spr.js +0 -345
- package/dist/esm/libs/render/cache/type.js +0 -0
- package/dist/esm/libs/render/cache/util.js +0 -105
- package/dist/esm/libs/render/reader.js +0 -196
- package/dist/esm-node/libs/render/cache/__tests__/cache.fun.test.js +0 -72
- package/dist/esm-node/libs/render/cache/__tests__/cache.test.js +0 -222
- package/dist/esm-node/libs/render/cache/__tests__/cacheable.js +0 -69
- package/dist/esm-node/libs/render/cache/__tests__/error-configuration.js +0 -47
- package/dist/esm-node/libs/render/cache/__tests__/matched-cache.js +0 -149
- package/dist/esm-node/libs/render/cache/index.js +0 -72
- package/dist/esm-node/libs/render/cache/page-caches/index.js +0 -12
- package/dist/esm-node/libs/render/cache/page-caches/lru.js +0 -32
- package/dist/esm-node/libs/render/cache/spr.js +0 -212
- package/dist/esm-node/libs/render/cache/type.js +0 -0
- package/dist/esm-node/libs/render/cache/util.js +0 -80
- package/dist/esm-node/libs/render/reader.js +0 -93
- package/dist/types/libs/render/cache/__tests__/cache.fun.test.d.ts +0 -1
- package/dist/types/libs/render/cache/__tests__/cache.test.d.ts +0 -1
- package/dist/types/libs/render/cache/__tests__/cacheable.d.ts +0 -62
- package/dist/types/libs/render/cache/__tests__/error-configuration.d.ts +0 -28
- package/dist/types/libs/render/cache/__tests__/matched-cache.d.ts +0 -124
- package/dist/types/libs/render/cache/index.d.ts +0 -6
- package/dist/types/libs/render/cache/page-caches/index.d.ts +0 -2
- package/dist/types/libs/render/cache/page-caches/lru.d.ts +0 -15
- package/dist/types/libs/render/cache/spr.d.ts +0 -22
- package/dist/types/libs/render/cache/type.d.ts +0 -48
- package/dist/types/libs/render/cache/util.d.ts +0 -18
- 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 {
|
|
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();
|
package/dist/esm/server/index.js
CHANGED
|
@@ -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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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: "
|
|
217
|
+
key: "onServerChange",
|
|
222
218
|
value: (
|
|
223
219
|
/* —————————————————————— function will be overwrite —————————————————————— */
|
|
224
|
-
function
|
|
225
|
-
|
|
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
|
|
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 {
|
|
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';
|