@modern-js/server-core 2.54.6 → 2.56.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/adapters/node/plugins/resource.js +1 -1
- package/dist/cjs/constants.js +12 -9
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/plugins/customServer/index.js +5 -5
- package/dist/cjs/plugins/index.js +7 -3
- package/dist/cjs/plugins/log.js +3 -3
- package/dist/cjs/plugins/monitors.js +183 -0
- package/dist/cjs/plugins/render/dataHandler.js +3 -2
- package/dist/cjs/plugins/render/index.js +6 -4
- package/dist/cjs/plugins/render/render.js +32 -15
- package/dist/cjs/plugins/render/ssrCache.js +72 -83
- package/dist/cjs/plugins/render/ssrRender.js +40 -145
- package/dist/cjs/types/requestHandler.js +16 -0
- package/dist/cjs/utils/error.js +3 -3
- package/dist/cjs/utils/transformStream.js +1 -1
- package/dist/esm/adapters/node/plugins/resource.js +1 -1
- package/dist/esm/constants.js +10 -8
- package/dist/esm/index.js +1 -0
- package/dist/esm/plugins/customServer/index.js +8 -8
- package/dist/esm/plugins/index.js +4 -2
- package/dist/esm/plugins/log.js +4 -4
- package/dist/esm/plugins/monitors.js +261 -0
- package/dist/esm/plugins/render/dataHandler.js +4 -3
- package/dist/esm/plugins/render/index.js +6 -4
- package/dist/esm/plugins/render/render.js +51 -24
- package/dist/esm/plugins/render/ssrCache.js +101 -131
- package/dist/esm/plugins/render/ssrRender.js +55 -175
- package/dist/esm/types/requestHandler.js +0 -0
- package/dist/esm/utils/error.js +3 -3
- package/dist/esm/utils/transformStream.js +16 -2
- package/dist/esm-node/adapters/node/plugins/resource.js +1 -1
- package/dist/esm-node/constants.js +10 -8
- package/dist/esm-node/index.js +1 -0
- package/dist/esm-node/plugins/customServer/index.js +6 -6
- package/dist/esm-node/plugins/index.js +4 -2
- package/dist/esm-node/plugins/log.js +3 -3
- package/dist/esm-node/plugins/monitors.js +156 -0
- package/dist/esm-node/plugins/render/dataHandler.js +3 -2
- package/dist/esm-node/plugins/render/index.js +5 -3
- package/dist/esm-node/plugins/render/render.js +33 -16
- package/dist/esm-node/plugins/render/ssrCache.js +73 -74
- package/dist/esm-node/plugins/render/ssrRender.js +43 -137
- package/dist/esm-node/types/requestHandler.js +0 -0
- package/dist/esm-node/utils/error.js +3 -3
- package/dist/esm-node/utils/transformStream.js +1 -1
- package/dist/types/constants.d.ts +2 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/plugins/index.d.ts +1 -1
- package/dist/types/plugins/monitors.d.ts +6 -0
- package/dist/types/plugins/render/dataHandler.d.ts +1 -1
- package/dist/types/plugins/render/render.d.ts +3 -2
- package/dist/types/plugins/render/ssrCache.d.ts +7 -11
- package/dist/types/plugins/render/ssrRender.d.ts +10 -10
- package/dist/types/types/config/html.d.ts +11 -0
- package/dist/types/types/config/output.d.ts +8 -0
- package/dist/types/types/render.d.ts +7 -4
- package/dist/types/types/requestHandler.d.ts +41 -0
- package/dist/types/types/server.d.ts +13 -4
- package/dist/types/utils/error.d.ts +2 -2
- package/dist/types/utils/transformStream.d.ts +1 -1
- package/package.json +7 -8
- package/dist/cjs/plugins/monitor.js +0 -87
- package/dist/cjs/plugins/render/serverTiming.js +0 -40
- package/dist/esm/plugins/monitor.js +0 -120
- package/dist/esm/plugins/render/serverTiming.js +0 -21
- package/dist/esm-node/plugins/monitor.js +0 -62
- package/dist/esm-node/plugins/render/serverTiming.js +0 -16
- package/dist/types/plugins/monitor.d.ts +0 -9
- package/dist/types/plugins/render/serverTiming.d.ts +0 -7
|
@@ -15,19 +15,21 @@ const REPLACE_REG = {
|
|
|
15
15
|
body: "</body>"
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
|
-
var
|
|
19
|
-
(function(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
})(
|
|
18
|
+
var ServerTimings;
|
|
19
|
+
(function(ServerTimings2) {
|
|
20
|
+
ServerTimings2["SERVER_HANDLE_REQUEST"] = "server-handle-request";
|
|
21
|
+
ServerTimings2["SERVER_MIDDLEWARE"] = "server-middleware";
|
|
22
|
+
ServerTimings2["SERVER_HOOK_AFTER_RENDER"] = "server-hook-after-render";
|
|
23
|
+
ServerTimings2["SERVER_HOOK_AFTER_MATCH"] = "server-hook-after-match";
|
|
24
|
+
})(ServerTimings || (ServerTimings = {}));
|
|
25
|
+
const SERVER_TIMING = "Server-Timing";
|
|
25
26
|
const X_RENDER_CACHE = "x-render-cache";
|
|
26
27
|
const X_MODERNJS_RENDER = "x-modernjs-render";
|
|
27
28
|
export {
|
|
28
29
|
AGGRED_DIR,
|
|
29
30
|
REPLACE_REG,
|
|
30
|
-
|
|
31
|
+
SERVER_TIMING,
|
|
32
|
+
ServerTimings,
|
|
31
33
|
X_MODERNJS_RENDER,
|
|
32
34
|
X_RENDER_CACHE
|
|
33
35
|
};
|
package/dist/esm-node/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { time } from "@modern-js/runtime-utils/time";
|
|
2
2
|
import { transformResponse } from "../../utils";
|
|
3
|
-
import {
|
|
3
|
+
import { ServerTimings } from "../../constants";
|
|
4
4
|
import { getLoaderCtx } from "./loader";
|
|
5
5
|
import { getAfterMatchCtx, getAfterRenderCtx, createCustomMiddlewaresCtx, createAfterStreamingRenderContext } from "./context";
|
|
6
6
|
import { createBaseHookContext } from "./base";
|
|
@@ -15,7 +15,7 @@ class CustomServer {
|
|
|
15
15
|
getHookMiddleware(entryName, routes) {
|
|
16
16
|
return async (c, next) => {
|
|
17
17
|
const routeInfo = routes.find((route) => route.entryName === entryName);
|
|
18
|
-
const
|
|
18
|
+
const monitors = c.get("monitors");
|
|
19
19
|
const baseHookCtx = createBaseHookContext(c);
|
|
20
20
|
const afterMatchCtx = getAfterMatchCtx(entryName, baseHookCtx);
|
|
21
21
|
const getCost = time();
|
|
@@ -23,7 +23,7 @@ class CustomServer {
|
|
|
23
23
|
onLast: noop
|
|
24
24
|
});
|
|
25
25
|
const cost = getCost();
|
|
26
|
-
cost && (
|
|
26
|
+
cost && (monitors === null || monitors === void 0 ? void 0 : monitors.timing(ServerTimings.SERVER_HOOK_AFTER_MATCH, cost));
|
|
27
27
|
const { url, status } = afterMatchCtx.router;
|
|
28
28
|
if (url) {
|
|
29
29
|
return c.redirect(url, status);
|
|
@@ -63,7 +63,7 @@ class CustomServer {
|
|
|
63
63
|
onLast: noop
|
|
64
64
|
});
|
|
65
65
|
const cost2 = getCost2();
|
|
66
|
-
cost2 && (
|
|
66
|
+
cost2 && (monitors === null || monitors === void 0 ? void 0 : monitors.timing(ServerTimings.SERVER_HOOK_AFTER_RENDER, cost2));
|
|
67
67
|
if (afterRenderCtx.response.private_overrided) {
|
|
68
68
|
return void 0;
|
|
69
69
|
}
|
|
@@ -82,7 +82,7 @@ class CustomServer {
|
|
|
82
82
|
}
|
|
83
83
|
return async (c, next) => {
|
|
84
84
|
var _c_env_node_res, _c_env_node, _c_env;
|
|
85
|
-
const
|
|
85
|
+
const monitors = c.get("monitors");
|
|
86
86
|
const locals = {};
|
|
87
87
|
const resArgs = {
|
|
88
88
|
headers: new Headers()
|
|
@@ -91,7 +91,7 @@ class CustomServer {
|
|
|
91
91
|
const getCost = time();
|
|
92
92
|
await serverMiddleware(customMiddlewareCtx);
|
|
93
93
|
const cost = getCost();
|
|
94
|
-
cost && (
|
|
94
|
+
cost && (monitors === null || monitors === void 0 ? void 0 : monitors.timing(ServerTimings.SERVER_MIDDLEWARE, cost));
|
|
95
95
|
c.set("locals", locals);
|
|
96
96
|
if (isRedirect(resArgs.headers, resArgs.status)) {
|
|
97
97
|
return c.redirect(resArgs.headers.get("Location") || "", resArgs.status || 302);
|
|
@@ -3,13 +3,15 @@ import { faviconPlugin } from "./favicon";
|
|
|
3
3
|
import { processedByPlugin } from "./processedBy";
|
|
4
4
|
import { getLoaderCtx } from "./customServer";
|
|
5
5
|
import { logPlugin } from "./log";
|
|
6
|
-
import {
|
|
6
|
+
import { initMonitorsPlugin, injectServerTiming, injectloggerPluigin } from "./monitors";
|
|
7
7
|
export {
|
|
8
8
|
faviconPlugin,
|
|
9
9
|
getLoaderCtx,
|
|
10
10
|
getRenderHandler,
|
|
11
|
+
initMonitorsPlugin,
|
|
12
|
+
injectServerTiming,
|
|
13
|
+
injectloggerPluigin,
|
|
11
14
|
logPlugin,
|
|
12
|
-
monitorPlugin,
|
|
13
15
|
processedByPlugin,
|
|
14
16
|
renderPlugin
|
|
15
17
|
};
|
|
@@ -39,13 +39,13 @@ function log(fn, prefix, method, path, status = 0, elapsed) {
|
|
|
39
39
|
function logHandler() {
|
|
40
40
|
return async function logger(c, next) {
|
|
41
41
|
const { method } = c.req;
|
|
42
|
-
const
|
|
43
|
-
if (!
|
|
42
|
+
const monitors = c.get("monitors");
|
|
43
|
+
if (!monitors) {
|
|
44
44
|
await next();
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
const path = getPathname(c.req.raw);
|
|
48
|
-
const logFn =
|
|
48
|
+
const logFn = monitors.debug;
|
|
49
49
|
log(logFn, "<--", method, path);
|
|
50
50
|
const start = Date.now();
|
|
51
51
|
await next();
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { time } from "@modern-js/runtime-utils/time";
|
|
2
|
+
import { SERVER_TIMING, ServerTimings } from "../constants";
|
|
3
|
+
function createMonitors() {
|
|
4
|
+
const coreMonitors = [];
|
|
5
|
+
const log = (level, message, args) => {
|
|
6
|
+
const event = {
|
|
7
|
+
type: "log",
|
|
8
|
+
payload: {
|
|
9
|
+
level,
|
|
10
|
+
message,
|
|
11
|
+
args
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
coreMonitors.forEach((monitor) => monitor(event));
|
|
15
|
+
};
|
|
16
|
+
const mointors = {
|
|
17
|
+
push(monitor) {
|
|
18
|
+
coreMonitors.push(monitor);
|
|
19
|
+
},
|
|
20
|
+
error(message, ...args) {
|
|
21
|
+
log("error", message, args);
|
|
22
|
+
},
|
|
23
|
+
warn(message, ...args) {
|
|
24
|
+
log("warn", message, args);
|
|
25
|
+
},
|
|
26
|
+
debug(message, ...args) {
|
|
27
|
+
log("debug", message, args);
|
|
28
|
+
},
|
|
29
|
+
info(message, ...args) {
|
|
30
|
+
log("info", message, args);
|
|
31
|
+
},
|
|
32
|
+
timing(name, dur, desc) {
|
|
33
|
+
const event = {
|
|
34
|
+
type: "timing",
|
|
35
|
+
payload: {
|
|
36
|
+
name,
|
|
37
|
+
dur,
|
|
38
|
+
desc
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
coreMonitors.forEach((monitor) => monitor(event));
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return mointors;
|
|
45
|
+
}
|
|
46
|
+
const initMonitorsPlugin = () => ({
|
|
47
|
+
name: "@modern-js/init-mointor",
|
|
48
|
+
setup(api) {
|
|
49
|
+
return {
|
|
50
|
+
prepare() {
|
|
51
|
+
const { middlewares } = api.useAppContext();
|
|
52
|
+
middlewares.push({
|
|
53
|
+
name: "init-monitor",
|
|
54
|
+
handler: async (c, next) => {
|
|
55
|
+
if (!c.get("monitors")) {
|
|
56
|
+
const monitors = createMonitors();
|
|
57
|
+
c.set("monitors", monitors);
|
|
58
|
+
}
|
|
59
|
+
return next();
|
|
60
|
+
},
|
|
61
|
+
order: "pre"
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const injectloggerPluigin = (logger) => ({
|
|
68
|
+
name: "@modern-js/inject-logger",
|
|
69
|
+
setup(api) {
|
|
70
|
+
return {
|
|
71
|
+
prepare() {
|
|
72
|
+
const { middlewares } = api.useAppContext();
|
|
73
|
+
middlewares.push({
|
|
74
|
+
name: "inject-logger",
|
|
75
|
+
handler: async (c, next) => {
|
|
76
|
+
if (!c.get("logger")) {
|
|
77
|
+
c.set("logger", logger);
|
|
78
|
+
}
|
|
79
|
+
const pathname = c.req.path;
|
|
80
|
+
const loggerMonitor = (event) => {
|
|
81
|
+
if (event.type === "log") {
|
|
82
|
+
const { level, message, args } = event.payload;
|
|
83
|
+
logger[level](message, ...args || []);
|
|
84
|
+
}
|
|
85
|
+
if (event.type === "timing") {
|
|
86
|
+
const { name, dur, desc } = event.payload;
|
|
87
|
+
if (desc) {
|
|
88
|
+
logger.debug(`%s Debug - ${name}, cost: %s, req.url = %s `, desc, dur, pathname);
|
|
89
|
+
} else {
|
|
90
|
+
logger.debug(`Debug - ${name}, cost: %s, req.url = %s`, dur, pathname);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const monitors = c.get("monitors");
|
|
95
|
+
monitors === null || monitors === void 0 ? void 0 : monitors.push(loggerMonitor);
|
|
96
|
+
return next();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const injectServerTiming = (metaName = "modern-js") => ({
|
|
104
|
+
name: "@modern-js/inject-server-timing",
|
|
105
|
+
setup(api) {
|
|
106
|
+
return {
|
|
107
|
+
prepare() {
|
|
108
|
+
const { middlewares } = api.useAppContext();
|
|
109
|
+
middlewares.push({
|
|
110
|
+
name: "inject-server-timing",
|
|
111
|
+
handler: async (c, next) => {
|
|
112
|
+
const serverTimings = [];
|
|
113
|
+
const timingMonitor = (event) => {
|
|
114
|
+
if (event.type === "timing") {
|
|
115
|
+
serverTimings.push(event.payload);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const monitors = c.get("monitors");
|
|
119
|
+
monitors === null || monitors === void 0 ? void 0 : monitors.push(timingMonitor);
|
|
120
|
+
await next();
|
|
121
|
+
serverTimings.forEach((serverTiming) => {
|
|
122
|
+
const { name, desc, dur } = serverTiming;
|
|
123
|
+
const _name = `bd-${metaName}-${name}`;
|
|
124
|
+
const value = `${_name};${desc ? `decs="${desc}";` : ""} dur=${dur}`;
|
|
125
|
+
c.header(SERVER_TIMING, value, {
|
|
126
|
+
append: true
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
function initReporter(entryName) {
|
|
136
|
+
return async (c, next) => {
|
|
137
|
+
const reporter = c.get("reporter");
|
|
138
|
+
if (!reporter) {
|
|
139
|
+
await next();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
await reporter.init({
|
|
143
|
+
entryName
|
|
144
|
+
});
|
|
145
|
+
const getCost = time();
|
|
146
|
+
await next();
|
|
147
|
+
const cost = getCost();
|
|
148
|
+
reporter.reportTiming(ServerTimings.SERVER_HANDLE_REQUEST, cost);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export {
|
|
152
|
+
initMonitorsPlugin,
|
|
153
|
+
initReporter,
|
|
154
|
+
injectServerTiming,
|
|
155
|
+
injectloggerPluigin
|
|
156
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MAIN_ENTRY_NAME } from "@modern-js/utils/universal/constants";
|
|
2
|
-
const dataHandler = async (request, { routeInfo, serverRoutes, reporter,
|
|
2
|
+
const dataHandler = async (request, { routeInfo, serverRoutes, reporter, onError, onTiming, serverManifest }) => {
|
|
3
3
|
var _serverManifest_loaderBundles;
|
|
4
4
|
const 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];
|
|
5
5
|
if (!serverLoaderModule) {
|
|
@@ -10,9 +10,10 @@ const dataHandler = async (request, { routeInfo, serverRoutes, reporter, logger,
|
|
|
10
10
|
request,
|
|
11
11
|
serverRoutes,
|
|
12
12
|
context: {
|
|
13
|
-
logger,
|
|
14
13
|
reporter
|
|
15
14
|
},
|
|
15
|
+
onTiming,
|
|
16
|
+
onError,
|
|
16
17
|
routes
|
|
17
18
|
});
|
|
18
19
|
return response;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MAIN_ENTRY_NAME } from "@modern-js/utils/universal/constants";
|
|
2
|
-
import { initReporter } from "../
|
|
2
|
+
import { initReporter } from "../monitors";
|
|
3
3
|
import { sortRoutes } from "../../utils";
|
|
4
4
|
import { getLoaderCtx, CustomServer, getServerMidFromUnstableMid } from "../customServer";
|
|
5
5
|
import { createRender } from "./render";
|
|
@@ -64,6 +64,7 @@ function createRenderHandler(render) {
|
|
|
64
64
|
var _c_env_node;
|
|
65
65
|
const logger = c.get("logger");
|
|
66
66
|
const reporter = c.get("reporter");
|
|
67
|
+
const monitors = c.get("monitors");
|
|
67
68
|
const templates = c.get("templates") || {};
|
|
68
69
|
const serverManifest = c.get("serverManifest") || {};
|
|
69
70
|
const locals = c.get("locals");
|
|
@@ -72,8 +73,9 @@ function createRenderHandler(render) {
|
|
|
72
73
|
const request = c.req.raw;
|
|
73
74
|
const nodeReq = (_c_env_node = c.env.node) === null || _c_env_node === void 0 ? void 0 : _c_env_node.req;
|
|
74
75
|
const res = await render(request, {
|
|
75
|
-
logger,
|
|
76
76
|
nodeReq,
|
|
77
|
+
monitors,
|
|
78
|
+
logger,
|
|
77
79
|
reporter,
|
|
78
80
|
templates,
|
|
79
81
|
metrics,
|
|
@@ -96,7 +98,7 @@ async function getRenderHandler({ pwd, routes, config, cacheConfig, metaName, st
|
|
|
96
98
|
const render = createRender({
|
|
97
99
|
routes,
|
|
98
100
|
pwd,
|
|
99
|
-
|
|
101
|
+
config,
|
|
100
102
|
staticGenerate,
|
|
101
103
|
cacheConfig,
|
|
102
104
|
forceCSR,
|
|
@@ -1,6 +1,6 @@
|
|
|
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
|
+
import { parseQuery, getPathname, createErrorHtml, sortRoutes, transformResponse, onError as onErrorFn, ErrorDigest, parseHeaders } from "../../utils";
|
|
4
4
|
import { REPLACE_REG, X_MODERNJS_RENDER } from "../../constants";
|
|
5
5
|
import { dataHandler } from "./dataHandler";
|
|
6
6
|
import { ssrRender } from "./ssrRender";
|
|
@@ -33,9 +33,17 @@ function matchRoute(router, request) {
|
|
|
33
33
|
const result = matched[0][0];
|
|
34
34
|
return result || [];
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
function getHeadersWithoutCookie(headers) {
|
|
37
|
+
const _headers = {
|
|
38
|
+
...headers,
|
|
39
|
+
cookie: void 0
|
|
40
|
+
};
|
|
41
|
+
delete _headers.cookie;
|
|
42
|
+
return _headers;
|
|
43
|
+
}
|
|
44
|
+
async function createRender({ routes, pwd, metaName, staticGenerate, cacheConfig, forceCSR, config, onFallback: onFallbackFn }) {
|
|
37
45
|
const router = getRouter(routes);
|
|
38
|
-
return async (req, { logger,
|
|
46
|
+
return async (req, { logger, reporter, metrics, monitors, nodeReq, templates, serverManifest, locals, loaderContext }) => {
|
|
39
47
|
const [routeInfo, params] = matchRoute(router, req);
|
|
40
48
|
const onFallback = async (reason, error) => {
|
|
41
49
|
return onFallbackFn === null || onFallbackFn === void 0 ? void 0 : onFallbackFn(reason, {
|
|
@@ -62,8 +70,16 @@ async function createRender({ routes, pwd, metaName, staticGenerate, cacheConfig
|
|
|
62
70
|
});
|
|
63
71
|
}
|
|
64
72
|
const renderMode = await getRenderMode(req, metaName || "modern-js", routeInfo.isSSR, forceCSR, nodeReq, onFallback);
|
|
65
|
-
const
|
|
66
|
-
|
|
73
|
+
const pathname = getPathname(req);
|
|
74
|
+
const headerData = parseHeaders(req);
|
|
75
|
+
const onError = (e) => {
|
|
76
|
+
monitors === null || monitors === void 0 ? void 0 : monitors.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));
|
|
77
|
+
};
|
|
78
|
+
const onTiming = (name, dur) => {
|
|
79
|
+
monitors === null || monitors === void 0 ? void 0 : monitors.timing(name, dur, "SSR");
|
|
80
|
+
};
|
|
81
|
+
const onBoundError = async (e) => {
|
|
82
|
+
onErrorFn(ErrorDigest.ERENDER, e, monitors, req);
|
|
67
83
|
await (onFallback === null || onFallback === void 0 ? void 0 : onFallback("error", e));
|
|
68
84
|
};
|
|
69
85
|
const renderOptions = {
|
|
@@ -71,32 +87,33 @@ async function createRender({ routes, pwd, metaName, staticGenerate, cacheConfig
|
|
|
71
87
|
html,
|
|
72
88
|
routeInfo,
|
|
73
89
|
staticGenerate: staticGenerate || false,
|
|
74
|
-
|
|
75
|
-
nonce,
|
|
76
|
-
logger,
|
|
90
|
+
config,
|
|
77
91
|
nodeReq,
|
|
78
92
|
cacheConfig,
|
|
79
93
|
reporter,
|
|
80
94
|
serverRoutes: routes,
|
|
81
95
|
params,
|
|
96
|
+
logger,
|
|
97
|
+
metrics,
|
|
82
98
|
locals,
|
|
83
99
|
serverManifest,
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
loaderContext: loaderContext || /* @__PURE__ */ new Map(),
|
|
101
|
+
onError,
|
|
102
|
+
onTiming
|
|
86
103
|
};
|
|
104
|
+
let response;
|
|
87
105
|
switch (renderMode) {
|
|
88
106
|
case "data":
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
response = await renderHandler(req, renderOptions, "ssr", onError);
|
|
92
|
-
}
|
|
93
|
-
return response;
|
|
107
|
+
response = await dataHandler(req, renderOptions) || await renderHandler(req, renderOptions, "ssr", onBoundError);
|
|
108
|
+
break;
|
|
94
109
|
case "ssr":
|
|
95
110
|
case "csr":
|
|
96
|
-
|
|
111
|
+
response = await renderHandler(req, renderOptions, renderMode, onBoundError);
|
|
112
|
+
break;
|
|
97
113
|
default:
|
|
98
114
|
throw new Error(`Unknown render mode: ${renderMode}`);
|
|
99
115
|
}
|
|
116
|
+
return response;
|
|
100
117
|
};
|
|
101
118
|
}
|
|
102
119
|
async function renderHandler(request, options, mode, onError) {
|
|
@@ -1,70 +1,40 @@
|
|
|
1
1
|
import { createMemoryStorage } from "@modern-js/runtime-utils/storer";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const cache = {
|
|
12
|
-
val: renderResult,
|
|
13
|
-
cursor: current
|
|
14
|
-
};
|
|
15
|
-
await container.set(key, JSON.stringify(cache), {
|
|
16
|
-
ttl
|
|
17
|
-
});
|
|
18
|
-
return {
|
|
19
|
-
data: renderResult,
|
|
20
|
-
status
|
|
21
|
-
};
|
|
22
|
-
} else {
|
|
23
|
-
const { Readable } = await import("stream").catch((_) => ({
|
|
24
|
-
Readable: void 0
|
|
25
|
-
}));
|
|
26
|
-
const runtimeEnv = getRuntimeEnv();
|
|
27
|
-
const streamModule = "../../adapters/node/polyfills/stream";
|
|
28
|
-
const { createReadableStreamFromReadable } = runtimeEnv === "node" ? await import(streamModule).catch((_) => ({
|
|
29
|
-
createReadableStreamFromReadable: void 0
|
|
30
|
-
})) : {
|
|
31
|
-
createReadableStreamFromReadable: void 0
|
|
32
|
-
};
|
|
33
|
-
const body = (
|
|
34
|
-
// TODO: remove node:stream, move it to ssr entry.
|
|
35
|
-
Readable && renderResult instanceof Readable ? createReadableStreamFromReadable === null || createReadableStreamFromReadable === void 0 ? void 0 : createReadableStreamFromReadable(renderResult) : renderResult
|
|
36
|
-
);
|
|
2
|
+
import { X_RENDER_CACHE } from "../../constants";
|
|
3
|
+
import { createTransformStream, getPathname } from "../../utils";
|
|
4
|
+
async function processCache({ request, key, requestHandler, requestHandlerOptions, ttl, container, cacheStatus }) {
|
|
5
|
+
const response = await requestHandler(request, requestHandlerOptions);
|
|
6
|
+
const decoder = new TextDecoder();
|
|
7
|
+
if (response.body) {
|
|
8
|
+
const stream = createTransformStream();
|
|
9
|
+
const reader = response.body.getReader();
|
|
10
|
+
const writer = stream.writable.getWriter();
|
|
37
11
|
let html = "";
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
12
|
+
const push = () => reader.read().then(({ done, value }) => {
|
|
13
|
+
if (done) {
|
|
14
|
+
const current = Date.now();
|
|
15
|
+
const cache = {
|
|
16
|
+
val: html,
|
|
17
|
+
cursor: current
|
|
18
|
+
};
|
|
19
|
+
container.set(key, JSON.stringify(cache), {
|
|
20
|
+
ttl
|
|
21
|
+
});
|
|
22
|
+
writer.close();
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const content = decoder.decode(value);
|
|
26
|
+
html += content;
|
|
27
|
+
writer.write(value);
|
|
28
|
+
push();
|
|
41
29
|
});
|
|
42
|
-
const reader = body.getReader();
|
|
43
|
-
const writer = stream.writable.getWriter();
|
|
44
|
-
const push = () => {
|
|
45
|
-
reader.read().then(({ done, value }) => {
|
|
46
|
-
if (done) {
|
|
47
|
-
const current = Date.now();
|
|
48
|
-
const cache = {
|
|
49
|
-
val: html,
|
|
50
|
-
cursor: current
|
|
51
|
-
};
|
|
52
|
-
container.set(key, JSON.stringify(cache), {
|
|
53
|
-
ttl
|
|
54
|
-
});
|
|
55
|
-
writer.close();
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
writer.write(value);
|
|
59
|
-
push();
|
|
60
|
-
});
|
|
61
|
-
};
|
|
62
30
|
push();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
status
|
|
66
|
-
|
|
31
|
+
cacheStatus && response.headers.set(X_RENDER_CACHE, cacheStatus);
|
|
32
|
+
return new Response(stream.readable, {
|
|
33
|
+
status: response.status,
|
|
34
|
+
headers: response.headers
|
|
35
|
+
});
|
|
67
36
|
}
|
|
37
|
+
return response;
|
|
68
38
|
}
|
|
69
39
|
const CACHE_NAMESPACE = "__ssr__cache";
|
|
70
40
|
const storage = createMemoryStorage(CACHE_NAMESPACE);
|
|
@@ -111,7 +81,7 @@ function matchCacheControl(cacheOption, req) {
|
|
|
111
81
|
}
|
|
112
82
|
}
|
|
113
83
|
async function getCacheResult(request, options) {
|
|
114
|
-
const { cacheControl,
|
|
84
|
+
const { cacheControl, container = storage, requestHandler, requestHandlerOptions } = options;
|
|
115
85
|
const key = computedKey(request, cacheControl);
|
|
116
86
|
const value = await container.get(key);
|
|
117
87
|
const { maxAge, staleWhileRevalidate } = cacheControl;
|
|
@@ -120,21 +90,50 @@ async function getCacheResult(request, options) {
|
|
|
120
90
|
const cache = JSON.parse(value);
|
|
121
91
|
const interval = Date.now() - cache.cursor;
|
|
122
92
|
if (interval <= maxAge) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
93
|
+
const cacheStatus = "hit";
|
|
94
|
+
return new Response(cache.val, {
|
|
95
|
+
headers: {
|
|
96
|
+
[X_RENDER_CACHE]: cacheStatus
|
|
97
|
+
}
|
|
98
|
+
});
|
|
127
99
|
} else if (interval <= staleWhileRevalidate + maxAge) {
|
|
128
|
-
processCache(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
100
|
+
processCache({
|
|
101
|
+
key,
|
|
102
|
+
request,
|
|
103
|
+
requestHandler,
|
|
104
|
+
requestHandlerOptions,
|
|
105
|
+
ttl,
|
|
106
|
+
container
|
|
107
|
+
}).then(async (response) => {
|
|
108
|
+
await response.text();
|
|
109
|
+
});
|
|
110
|
+
const cacheStatus = "stale";
|
|
111
|
+
return new Response(cache.val, {
|
|
112
|
+
headers: {
|
|
113
|
+
[X_RENDER_CACHE]: cacheStatus
|
|
114
|
+
}
|
|
115
|
+
});
|
|
133
116
|
} else {
|
|
134
|
-
return processCache(
|
|
117
|
+
return processCache({
|
|
118
|
+
key,
|
|
119
|
+
request,
|
|
120
|
+
requestHandler,
|
|
121
|
+
requestHandlerOptions,
|
|
122
|
+
ttl,
|
|
123
|
+
container,
|
|
124
|
+
cacheStatus: "expired"
|
|
125
|
+
});
|
|
135
126
|
}
|
|
136
127
|
} else {
|
|
137
|
-
return processCache(
|
|
128
|
+
return processCache({
|
|
129
|
+
key,
|
|
130
|
+
request,
|
|
131
|
+
requestHandler,
|
|
132
|
+
requestHandlerOptions,
|
|
133
|
+
ttl,
|
|
134
|
+
container,
|
|
135
|
+
cacheStatus: "miss"
|
|
136
|
+
});
|
|
138
137
|
}
|
|
139
138
|
}
|
|
140
139
|
export {
|