@modern-js/server-core 3.9.1 → 3.9.3
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/node.js +3 -1
- package/dist/cjs/adapters/node/plugins/static.js +1 -1
- package/dist/cjs/helper.js +1 -1
- package/dist/cjs/plugins/render/render.js +3 -4
- package/dist/cjs/plugins/render/ssrCache.js +68 -35
- package/dist/cjs/serverBase.js +2 -2
- package/dist/cjs/utils/transformStream.js +1 -1
- package/dist/esm/adapters/node/node.mjs +3 -1
- package/dist/esm/adapters/node/plugins/static.mjs +1 -1
- package/dist/esm/helper.mjs +1 -1
- package/dist/esm/plugins/render/render.mjs +4 -11
- package/dist/esm/plugins/render/ssrCache.mjs +68 -35
- package/dist/esm/serverBase.mjs +2 -2
- package/dist/esm/utils/transformStream.mjs +1 -1
- package/dist/esm-node/adapters/node/node.mjs +3 -1
- package/dist/esm-node/adapters/node/plugins/static.mjs +1 -1
- package/dist/esm-node/helper.mjs +1 -1
- package/dist/esm-node/plugins/render/render.mjs +4 -11
- package/dist/esm-node/plugins/render/ssrCache.mjs +68 -35
- package/dist/esm-node/serverBase.mjs +2 -2
- package/dist/esm-node/utils/transformStream.mjs +1 -1
- package/dist/types/adapters/node/plugins/static.d.ts +2 -2
- package/package.json +7 -7
- package/dist/esm/rslib-runtime~1.mjs +0 -18
- package/dist/esm-node/rslib-runtime~0.mjs +0 -19
|
@@ -68,7 +68,9 @@ const createWebRequest = (req, res, body)=>{
|
|
|
68
68
|
headers: headerRecord,
|
|
69
69
|
signal: controller.signal
|
|
70
70
|
};
|
|
71
|
-
res.on('close', ()=>
|
|
71
|
+
res.on('close', ()=>{
|
|
72
|
+
if (!res.writableFinished || req.aborted) controller.abort('res closed');
|
|
73
|
+
});
|
|
72
74
|
const url = `http://${req.headers.host}${req.url}`;
|
|
73
75
|
const needsRequestBody = body || !('GET' === method || 'HEAD' === method);
|
|
74
76
|
const cloneableReq = needsRequestBody ? external_cloneable_readable_default()(req) : null;
|
|
@@ -143,7 +143,7 @@ function createStaticMiddleware(options) {
|
|
|
143
143
|
pwd,
|
|
144
144
|
routes: routes || []
|
|
145
145
|
})(c, next);
|
|
146
|
-
{
|
|
146
|
+
else {
|
|
147
147
|
const filepath = external_path_default().join(pwd, pathname.replace(pathPrefix, ()=>''));
|
|
148
148
|
if (!isPathInside(filepath, pwd)) return next();
|
|
149
149
|
if (!await utils_namespaceObject.fs.pathExists(filepath)) return next();
|
package/dist/cjs/helper.js
CHANGED
|
@@ -31,7 +31,7 @@ const LOADER_CONTEXT = 'loaderContext';
|
|
|
31
31
|
function getLoaderCtx(c) {
|
|
32
32
|
const loaderContext = c.get(LOADER_CONTEXT);
|
|
33
33
|
if (loaderContext) return loaderContext;
|
|
34
|
-
{
|
|
34
|
+
else {
|
|
35
35
|
const loaderContext = new Map();
|
|
36
36
|
c.set(LOADER_CONTEXT, loaderContext);
|
|
37
37
|
return loaderContext;
|
|
@@ -87,8 +87,7 @@ var __webpack_exports__ = {};
|
|
|
87
87
|
void 0,
|
|
88
88
|
{}
|
|
89
89
|
];
|
|
90
|
-
}
|
|
91
|
-
{
|
|
90
|
+
} else {
|
|
92
91
|
const result = matchedRoutes[0];
|
|
93
92
|
if (!result) return [
|
|
94
93
|
void 0,
|
|
@@ -242,7 +241,7 @@ var __webpack_exports__ = {};
|
|
|
242
241
|
if (req.headers.get('x-rsc-action')) return 'rsc-action';
|
|
243
242
|
if (req.headers.get('x-rsc-tree')) return 'rsc-tree';
|
|
244
243
|
if (!isSSR) return 'csr';
|
|
245
|
-
{
|
|
244
|
+
else {
|
|
246
245
|
if (query.__loader) return 'data';
|
|
247
246
|
const fallbackHeaderValue = req.headers.get(fallbackHeader) || nodeReq?.headers[fallbackHeader];
|
|
248
247
|
if (forceCSR && (query.csr || fallbackHeaderValue || contextForceCSR)) {
|
|
@@ -271,7 +270,7 @@ var __webpack_exports__ = {};
|
|
|
271
270
|
[external_constants_js_namespaceObject.X_MODERNJS_RENDER]: 'client'
|
|
272
271
|
})
|
|
273
272
|
});
|
|
274
|
-
return (0, external_csrRscRender_js_namespaceObject.csrRscRender)(request, options);
|
|
273
|
+
else return (0, external_csrRscRender_js_namespaceObject.csrRscRender)(request, options);
|
|
275
274
|
}
|
|
276
275
|
})();
|
|
277
276
|
exports.createRender = __webpack_exports__.createRender;
|
|
@@ -59,30 +59,59 @@ async function processCache({ request, key, requestHandler, requestHandlerOption
|
|
|
59
59
|
const reader = response.body.getReader();
|
|
60
60
|
const writer = stream.writable.getWriter();
|
|
61
61
|
let html = '';
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
let cancelled = false;
|
|
63
|
+
const cancel = async (reason)=>{
|
|
64
|
+
cancelled = true;
|
|
65
|
+
await reader.cancel(reason);
|
|
66
|
+
};
|
|
67
|
+
writer.closed.catch(cancel).catch(()=>{});
|
|
68
|
+
const onAbort = ()=>{
|
|
69
|
+
Promise.allSettled([
|
|
70
|
+
cancel(request.signal.reason),
|
|
71
|
+
writer.abort(request.signal.reason)
|
|
72
|
+
]);
|
|
73
|
+
};
|
|
74
|
+
request.signal.addEventListener('abort', onAbort, {
|
|
75
|
+
once: true
|
|
76
|
+
});
|
|
77
|
+
if (request.signal.aborted) onAbort();
|
|
78
|
+
const pumping = (async ()=>{
|
|
79
|
+
try {
|
|
80
|
+
for(;;){
|
|
81
|
+
const { done, value } = await reader.read();
|
|
82
|
+
if (cancelled) return;
|
|
83
|
+
if (done) break;
|
|
84
|
+
html += decoder.decode(value, {
|
|
85
|
+
stream: true
|
|
86
|
+
});
|
|
87
|
+
await writer.write(value);
|
|
88
|
+
}
|
|
89
|
+
html += decoder.decode();
|
|
90
|
+
await writer.close();
|
|
91
|
+
if (!cancelled && !ZERO_RENDER_LEVEL.test(html) && !NO_SSR_CACHE.test(html)) {
|
|
67
92
|
const cache = {
|
|
68
93
|
val: html,
|
|
69
|
-
cursor:
|
|
94
|
+
cursor: Date.now()
|
|
70
95
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
96
|
+
try {
|
|
97
|
+
await container.set(key, JSON.stringify(cache), {
|
|
98
|
+
ttl
|
|
99
|
+
});
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (onError) onError(error, 'render-cache');
|
|
102
|
+
else console.error(`[render-cache] set cache failed, key: ${key}`, error);
|
|
103
|
+
}
|
|
79
104
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
105
|
+
} catch (error) {
|
|
106
|
+
await Promise.allSettled([
|
|
107
|
+
cancel(error),
|
|
108
|
+
writer.abort(error)
|
|
109
|
+
]);
|
|
110
|
+
} finally{
|
|
111
|
+
request.signal.removeEventListener('abort', onAbort);
|
|
112
|
+
}
|
|
113
|
+
})();
|
|
114
|
+
pumping.catch(()=>{});
|
|
86
115
|
cacheStatus && response.headers.set(external_constants_js_namespaceObject.X_RENDER_CACHE, cacheStatus);
|
|
87
116
|
return new Response(stream.readable, {
|
|
88
117
|
status: response.status,
|
|
@@ -98,8 +127,8 @@ function computedKey(req, cacheControl) {
|
|
|
98
127
|
const { customKey } = cacheControl;
|
|
99
128
|
const defaultKey = '/' === pathname ? pathname : removeTailSlash(pathname);
|
|
100
129
|
if (!customKey) return defaultKey;
|
|
101
|
-
if ('string' == typeof customKey) return customKey;
|
|
102
|
-
return customKey(defaultKey);
|
|
130
|
+
else if ('string' == typeof customKey) return customKey;
|
|
131
|
+
else return customKey(defaultKey);
|
|
103
132
|
}
|
|
104
133
|
function shouldUseCache(request) {
|
|
105
134
|
const url = new URL(request.url);
|
|
@@ -110,7 +139,7 @@ function shouldUseCache(request) {
|
|
|
110
139
|
}
|
|
111
140
|
function matchCacheControl(cacheOption, req) {
|
|
112
141
|
if (!cacheOption || !req) return;
|
|
113
|
-
{
|
|
142
|
+
else {
|
|
114
143
|
if (isCacheControl(cacheOption)) return cacheOption;
|
|
115
144
|
if (isCacheOptionProvider(cacheOption)) return cacheOption(req);
|
|
116
145
|
const url = req.url;
|
|
@@ -149,7 +178,7 @@ async function getCacheResult(request, options) {
|
|
|
149
178
|
container,
|
|
150
179
|
cacheStatus: 'miss'
|
|
151
180
|
});
|
|
152
|
-
{
|
|
181
|
+
else {
|
|
153
182
|
const cache = JSON.parse(value);
|
|
154
183
|
const interval = Date.now() - cache.cursor;
|
|
155
184
|
if (interval <= maxAge) {
|
|
@@ -159,17 +188,16 @@ async function getCacheResult(request, options) {
|
|
|
159
188
|
[external_constants_js_namespaceObject.X_RENDER_CACHE]: cacheStatus
|
|
160
189
|
}
|
|
161
190
|
});
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
{
|
|
191
|
+
} else {
|
|
192
|
+
if (!(interval <= staleWhileRevalidate + maxAge)) return processCache({
|
|
193
|
+
key,
|
|
194
|
+
request,
|
|
195
|
+
requestHandler,
|
|
196
|
+
requestHandlerOptions,
|
|
197
|
+
ttl,
|
|
198
|
+
container,
|
|
199
|
+
cacheStatus: 'expired'
|
|
200
|
+
});
|
|
173
201
|
processCache({
|
|
174
202
|
key,
|
|
175
203
|
request,
|
|
@@ -179,6 +207,11 @@ async function getCacheResult(request, options) {
|
|
|
179
207
|
container
|
|
180
208
|
}).then(async (response)=>{
|
|
181
209
|
await response.text();
|
|
210
|
+
}).catch((error)=>{
|
|
211
|
+
try {
|
|
212
|
+
if (onError) onError(error, 'render-cache');
|
|
213
|
+
else console.error('[render-cache] revalidation failed', error);
|
|
214
|
+
} catch {}
|
|
182
215
|
});
|
|
183
216
|
const cacheStatus = 'stale';
|
|
184
217
|
return new Response(cache.val, {
|
package/dist/cjs/serverBase.js
CHANGED
|
@@ -138,7 +138,7 @@ function applyMiddlewares() {
|
|
|
138
138
|
if (middleware.before) {
|
|
139
139
|
const targetIndex = finalMiddlewares.findIndex((item)=>{
|
|
140
140
|
if (middleware.before?.includes(item.name)) return true;
|
|
141
|
-
return false;
|
|
141
|
+
else return false;
|
|
142
142
|
});
|
|
143
143
|
if (-1 !== targetIndex) finalMiddlewares.splice(targetIndex, 0, middleware);
|
|
144
144
|
else finalMiddlewares.push(middleware);
|
|
@@ -159,7 +159,7 @@ function applyMiddlewares() {
|
|
|
159
159
|
}
|
|
160
160
|
function handler2Handlers(handler) {
|
|
161
161
|
if (Array.isArray(handler)) return handler;
|
|
162
|
-
return [
|
|
162
|
+
else return [
|
|
163
163
|
handler
|
|
164
164
|
];
|
|
165
165
|
}
|
|
@@ -43,7 +43,7 @@ function transformResponse(response, transformCb) {
|
|
|
43
43
|
if (response.body) {
|
|
44
44
|
const stream = createTransformStream(async (before)=>{
|
|
45
45
|
if (Array.isArray(transformCb)) return transformCb.reduce(async (before, cb)=>cb(await before), Promise.resolve(before));
|
|
46
|
-
return transformCb(before);
|
|
46
|
+
else return transformCb(before);
|
|
47
47
|
});
|
|
48
48
|
response.body.pipeThrough(stream);
|
|
49
49
|
readable = stream.readable;
|
|
@@ -24,7 +24,9 @@ const createWebRequest = (req, res, body)=>{
|
|
|
24
24
|
headers: headerRecord,
|
|
25
25
|
signal: controller.signal
|
|
26
26
|
};
|
|
27
|
-
res.on('close', ()=>
|
|
27
|
+
res.on('close', ()=>{
|
|
28
|
+
if (!res.writableFinished || req.aborted) controller.abort('res closed');
|
|
29
|
+
});
|
|
28
30
|
const url = `http://${req.headers.host}${req.url}`;
|
|
29
31
|
const needsRequestBody = body || !('GET' === method || 'HEAD' === method);
|
|
30
32
|
const cloneableReq = needsRequestBody ? cloneable_readable(req) : null;
|
|
@@ -99,7 +99,7 @@ function createStaticMiddleware(options) {
|
|
|
99
99
|
pwd,
|
|
100
100
|
routes: routes || []
|
|
101
101
|
})(c, next);
|
|
102
|
-
{
|
|
102
|
+
else {
|
|
103
103
|
const filepath = path.join(pwd, pathname.replace(pathPrefix, ()=>''));
|
|
104
104
|
if (!isPathInside(filepath, pwd)) return next();
|
|
105
105
|
if (!await fs.pathExists(filepath)) return next();
|
package/dist/esm/helper.mjs
CHANGED
|
@@ -2,7 +2,7 @@ const LOADER_CONTEXT = 'loaderContext';
|
|
|
2
2
|
function getLoaderCtx(c) {
|
|
3
3
|
const loaderContext = c.get(LOADER_CONTEXT);
|
|
4
4
|
if (loaderContext) return loaderContext;
|
|
5
|
-
{
|
|
5
|
+
else {
|
|
6
6
|
const loaderContext = new Map();
|
|
7
7
|
c.set(LOADER_CONTEXT, loaderContext);
|
|
8
8
|
return loaderContext;
|
|
@@ -7,12 +7,6 @@ import { dataHandler } from "./dataHandler.mjs";
|
|
|
7
7
|
import { renderRscHandler } from "./renderRscHandler.mjs";
|
|
8
8
|
import { serverActionHandler } from "./serverActionHandler.mjs";
|
|
9
9
|
import { ssrRender } from "./ssrRender.mjs";
|
|
10
|
-
import { __webpack_require__ } from "../../rslib-runtime~1.mjs";
|
|
11
|
-
__webpack_require__.add({
|
|
12
|
-
718 (module) {
|
|
13
|
-
module.exports = require("@modern-js/runtime-utils/router");
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
10
|
const DYNAMIC_ROUTE_REG = /\/:./;
|
|
17
11
|
function getRouter(routes) {
|
|
18
12
|
const dynamicRoutes = [];
|
|
@@ -45,8 +39,7 @@ function matchRoute(router, pathname, entryName) {
|
|
|
45
39
|
void 0,
|
|
46
40
|
{}
|
|
47
41
|
];
|
|
48
|
-
}
|
|
49
|
-
{
|
|
42
|
+
} else {
|
|
50
43
|
const result = matchedRoutes[0];
|
|
51
44
|
if (!result) return [
|
|
52
45
|
void 0,
|
|
@@ -162,7 +155,7 @@ async function renderHandler(request, options, mode, fallbackWrapper, framework)
|
|
|
162
155
|
const { nestedRoutesJson } = serverManifest;
|
|
163
156
|
const routes = nestedRoutesJson?.[options.routeInfo.entryName];
|
|
164
157
|
if (routes) {
|
|
165
|
-
const { matchRoutes } =
|
|
158
|
+
const { matchRoutes } = require("@modern-js/runtime-utils/router");
|
|
166
159
|
const url = new URL(request.url);
|
|
167
160
|
const matchedRoutes = matchRoutes(routes, url.pathname, options.routeInfo.urlPath);
|
|
168
161
|
if (matchedRoutes) {
|
|
@@ -200,7 +193,7 @@ async function getRenderMode(req, fallbackHeader, isSSR, forceCSR, nodeReq, onFa
|
|
|
200
193
|
if (req.headers.get('x-rsc-action')) return 'rsc-action';
|
|
201
194
|
if (req.headers.get('x-rsc-tree')) return 'rsc-tree';
|
|
202
195
|
if (!isSSR) return 'csr';
|
|
203
|
-
{
|
|
196
|
+
else {
|
|
204
197
|
if (query.__loader) return 'data';
|
|
205
198
|
const fallbackHeaderValue = req.headers.get(fallbackHeader) || nodeReq?.headers[fallbackHeader];
|
|
206
199
|
if (forceCSR && (query.csr || fallbackHeaderValue || contextForceCSR)) {
|
|
@@ -229,6 +222,6 @@ async function csrRender(request, options) {
|
|
|
229
222
|
[X_MODERNJS_RENDER]: 'client'
|
|
230
223
|
})
|
|
231
224
|
});
|
|
232
|
-
return csrRscRender(request, options);
|
|
225
|
+
else return csrRscRender(request, options);
|
|
233
226
|
}
|
|
234
227
|
export { createRender, matchRoute };
|
|
@@ -25,30 +25,59 @@ async function processCache({ request, key, requestHandler, requestHandlerOption
|
|
|
25
25
|
const reader = response.body.getReader();
|
|
26
26
|
const writer = stream.writable.getWriter();
|
|
27
27
|
let html = '';
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
let cancelled = false;
|
|
29
|
+
const cancel = async (reason)=>{
|
|
30
|
+
cancelled = true;
|
|
31
|
+
await reader.cancel(reason);
|
|
32
|
+
};
|
|
33
|
+
writer.closed.catch(cancel).catch(()=>{});
|
|
34
|
+
const onAbort = ()=>{
|
|
35
|
+
Promise.allSettled([
|
|
36
|
+
cancel(request.signal.reason),
|
|
37
|
+
writer.abort(request.signal.reason)
|
|
38
|
+
]);
|
|
39
|
+
};
|
|
40
|
+
request.signal.addEventListener('abort', onAbort, {
|
|
41
|
+
once: true
|
|
42
|
+
});
|
|
43
|
+
if (request.signal.aborted) onAbort();
|
|
44
|
+
const pumping = (async ()=>{
|
|
45
|
+
try {
|
|
46
|
+
for(;;){
|
|
47
|
+
const { done, value } = await reader.read();
|
|
48
|
+
if (cancelled) return;
|
|
49
|
+
if (done) break;
|
|
50
|
+
html += decoder.decode(value, {
|
|
51
|
+
stream: true
|
|
52
|
+
});
|
|
53
|
+
await writer.write(value);
|
|
54
|
+
}
|
|
55
|
+
html += decoder.decode();
|
|
56
|
+
await writer.close();
|
|
57
|
+
if (!cancelled && !ZERO_RENDER_LEVEL.test(html) && !NO_SSR_CACHE.test(html)) {
|
|
33
58
|
const cache = {
|
|
34
59
|
val: html,
|
|
35
|
-
cursor:
|
|
60
|
+
cursor: Date.now()
|
|
36
61
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
try {
|
|
63
|
+
await container.set(key, JSON.stringify(cache), {
|
|
64
|
+
ttl
|
|
65
|
+
});
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (onError) onError(error, 'render-cache');
|
|
68
|
+
else console.error(`[render-cache] set cache failed, key: ${key}`, error);
|
|
69
|
+
}
|
|
45
70
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
71
|
+
} catch (error) {
|
|
72
|
+
await Promise.allSettled([
|
|
73
|
+
cancel(error),
|
|
74
|
+
writer.abort(error)
|
|
75
|
+
]);
|
|
76
|
+
} finally{
|
|
77
|
+
request.signal.removeEventListener('abort', onAbort);
|
|
78
|
+
}
|
|
79
|
+
})();
|
|
80
|
+
pumping.catch(()=>{});
|
|
52
81
|
cacheStatus && response.headers.set(X_RENDER_CACHE, cacheStatus);
|
|
53
82
|
return new Response(stream.readable, {
|
|
54
83
|
status: response.status,
|
|
@@ -64,8 +93,8 @@ function computedKey(req, cacheControl) {
|
|
|
64
93
|
const { customKey } = cacheControl;
|
|
65
94
|
const defaultKey = '/' === pathname ? pathname : removeTailSlash(pathname);
|
|
66
95
|
if (!customKey) return defaultKey;
|
|
67
|
-
if ('string' == typeof customKey) return customKey;
|
|
68
|
-
return customKey(defaultKey);
|
|
96
|
+
else if ('string' == typeof customKey) return customKey;
|
|
97
|
+
else return customKey(defaultKey);
|
|
69
98
|
}
|
|
70
99
|
function shouldUseCache(request) {
|
|
71
100
|
const url = new URL(request.url);
|
|
@@ -76,7 +105,7 @@ function shouldUseCache(request) {
|
|
|
76
105
|
}
|
|
77
106
|
function matchCacheControl(cacheOption, req) {
|
|
78
107
|
if (!cacheOption || !req) return;
|
|
79
|
-
{
|
|
108
|
+
else {
|
|
80
109
|
if (isCacheControl(cacheOption)) return cacheOption;
|
|
81
110
|
if (isCacheOptionProvider(cacheOption)) return cacheOption(req);
|
|
82
111
|
const url = req.url;
|
|
@@ -115,7 +144,7 @@ async function getCacheResult(request, options) {
|
|
|
115
144
|
container,
|
|
116
145
|
cacheStatus: 'miss'
|
|
117
146
|
});
|
|
118
|
-
{
|
|
147
|
+
else {
|
|
119
148
|
const cache = JSON.parse(value);
|
|
120
149
|
const interval = Date.now() - cache.cursor;
|
|
121
150
|
if (interval <= maxAge) {
|
|
@@ -125,17 +154,16 @@ async function getCacheResult(request, options) {
|
|
|
125
154
|
[X_RENDER_CACHE]: cacheStatus
|
|
126
155
|
}
|
|
127
156
|
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
{
|
|
157
|
+
} else {
|
|
158
|
+
if (!(interval <= staleWhileRevalidate + maxAge)) return processCache({
|
|
159
|
+
key,
|
|
160
|
+
request,
|
|
161
|
+
requestHandler,
|
|
162
|
+
requestHandlerOptions,
|
|
163
|
+
ttl,
|
|
164
|
+
container,
|
|
165
|
+
cacheStatus: 'expired'
|
|
166
|
+
});
|
|
139
167
|
processCache({
|
|
140
168
|
key,
|
|
141
169
|
request,
|
|
@@ -145,6 +173,11 @@ async function getCacheResult(request, options) {
|
|
|
145
173
|
container
|
|
146
174
|
}).then(async (response)=>{
|
|
147
175
|
await response.text();
|
|
176
|
+
}).catch((error)=>{
|
|
177
|
+
try {
|
|
178
|
+
if (onError) onError(error, 'render-cache');
|
|
179
|
+
else console.error('[render-cache] revalidation failed', error);
|
|
180
|
+
} catch {}
|
|
148
181
|
});
|
|
149
182
|
const cacheStatus = 'stale';
|
|
150
183
|
return new Response(cache.val, {
|
package/dist/esm/serverBase.mjs
CHANGED
|
@@ -105,7 +105,7 @@ function applyMiddlewares() {
|
|
|
105
105
|
if (middleware.before) {
|
|
106
106
|
const targetIndex = finalMiddlewares.findIndex((item)=>{
|
|
107
107
|
if (middleware.before?.includes(item.name)) return true;
|
|
108
|
-
return false;
|
|
108
|
+
else return false;
|
|
109
109
|
});
|
|
110
110
|
if (-1 !== targetIndex) finalMiddlewares.splice(targetIndex, 0, middleware);
|
|
111
111
|
else finalMiddlewares.push(middleware);
|
|
@@ -126,7 +126,7 @@ function applyMiddlewares() {
|
|
|
126
126
|
}
|
|
127
127
|
function handler2Handlers(handler) {
|
|
128
128
|
if (Array.isArray(handler)) return handler;
|
|
129
|
-
return [
|
|
129
|
+
else return [
|
|
130
130
|
handler
|
|
131
131
|
];
|
|
132
132
|
}
|
|
@@ -14,7 +14,7 @@ function transformResponse(response, transformCb) {
|
|
|
14
14
|
if (response.body) {
|
|
15
15
|
const stream = createTransformStream(async (before)=>{
|
|
16
16
|
if (Array.isArray(transformCb)) return transformCb.reduce(async (before, cb)=>cb(await before), Promise.resolve(before));
|
|
17
|
-
return transformCb(before);
|
|
17
|
+
else return transformCb(before);
|
|
18
18
|
});
|
|
19
19
|
response.body.pipeThrough(stream);
|
|
20
20
|
readable = stream.readable;
|
|
@@ -25,7 +25,9 @@ const createWebRequest = (req, res, body)=>{
|
|
|
25
25
|
headers: headerRecord,
|
|
26
26
|
signal: controller.signal
|
|
27
27
|
};
|
|
28
|
-
res.on('close', ()=>
|
|
28
|
+
res.on('close', ()=>{
|
|
29
|
+
if (!res.writableFinished || req.aborted) controller.abort('res closed');
|
|
30
|
+
});
|
|
29
31
|
const url = `http://${req.headers.host}${req.url}`;
|
|
30
32
|
const needsRequestBody = body || !('GET' === method || 'HEAD' === method);
|
|
31
33
|
const cloneableReq = needsRequestBody ? cloneable_readable(req) : null;
|
|
@@ -100,7 +100,7 @@ function createStaticMiddleware(options) {
|
|
|
100
100
|
pwd,
|
|
101
101
|
routes: routes || []
|
|
102
102
|
})(c, next);
|
|
103
|
-
{
|
|
103
|
+
else {
|
|
104
104
|
const filepath = path.join(pwd, pathname.replace(pathPrefix, ()=>''));
|
|
105
105
|
if (!isPathInside(filepath, pwd)) return next();
|
|
106
106
|
if (!await fs.pathExists(filepath)) return next();
|
package/dist/esm-node/helper.mjs
CHANGED
|
@@ -3,7 +3,7 @@ const LOADER_CONTEXT = 'loaderContext';
|
|
|
3
3
|
function getLoaderCtx(c) {
|
|
4
4
|
const loaderContext = c.get(LOADER_CONTEXT);
|
|
5
5
|
if (loaderContext) return loaderContext;
|
|
6
|
-
{
|
|
6
|
+
else {
|
|
7
7
|
const loaderContext = new Map();
|
|
8
8
|
c.set(LOADER_CONTEXT, loaderContext);
|
|
9
9
|
return loaderContext;
|
|
@@ -8,14 +8,8 @@ import { dataHandler } from "./dataHandler.mjs";
|
|
|
8
8
|
import { renderRscHandler } from "./renderRscHandler.mjs";
|
|
9
9
|
import { serverActionHandler } from "./serverActionHandler.mjs";
|
|
10
10
|
import { ssrRender } from "./ssrRender.mjs";
|
|
11
|
-
import { __webpack_require__ } from "../../rslib-runtime~0.mjs";
|
|
12
11
|
import { createRequire as __rspack_createRequire } from "node:module";
|
|
13
12
|
const __rspack_createRequire_require = __rspack_createRequire(import.meta.url);
|
|
14
|
-
__webpack_require__.add({
|
|
15
|
-
"@modern-js/runtime-utils/router" (module) {
|
|
16
|
-
module.exports = __rspack_createRequire_require("@modern-js/runtime-utils/router");
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
13
|
const DYNAMIC_ROUTE_REG = /\/:./;
|
|
20
14
|
function getRouter(routes) {
|
|
21
15
|
const dynamicRoutes = [];
|
|
@@ -48,8 +42,7 @@ function matchRoute(router, pathname, entryName) {
|
|
|
48
42
|
void 0,
|
|
49
43
|
{}
|
|
50
44
|
];
|
|
51
|
-
}
|
|
52
|
-
{
|
|
45
|
+
} else {
|
|
53
46
|
const result = matchedRoutes[0];
|
|
54
47
|
if (!result) return [
|
|
55
48
|
void 0,
|
|
@@ -165,7 +158,7 @@ async function renderHandler(request, options, mode, fallbackWrapper, framework)
|
|
|
165
158
|
const { nestedRoutesJson } = serverManifest;
|
|
166
159
|
const routes = nestedRoutesJson?.[options.routeInfo.entryName];
|
|
167
160
|
if (routes) {
|
|
168
|
-
const { matchRoutes } =
|
|
161
|
+
const { matchRoutes } = __rspack_createRequire_require("@modern-js/runtime-utils/router");
|
|
169
162
|
const url = new URL(request.url);
|
|
170
163
|
const matchedRoutes = matchRoutes(routes, url.pathname, options.routeInfo.urlPath);
|
|
171
164
|
if (matchedRoutes) {
|
|
@@ -203,7 +196,7 @@ async function getRenderMode(req, fallbackHeader, isSSR, forceCSR, nodeReq, onFa
|
|
|
203
196
|
if (req.headers.get('x-rsc-action')) return 'rsc-action';
|
|
204
197
|
if (req.headers.get('x-rsc-tree')) return 'rsc-tree';
|
|
205
198
|
if (!isSSR) return 'csr';
|
|
206
|
-
{
|
|
199
|
+
else {
|
|
207
200
|
if (query.__loader) return 'data';
|
|
208
201
|
const fallbackHeaderValue = req.headers.get(fallbackHeader) || nodeReq?.headers[fallbackHeader];
|
|
209
202
|
if (forceCSR && (query.csr || fallbackHeaderValue || contextForceCSR)) {
|
|
@@ -232,6 +225,6 @@ async function csrRender(request, options) {
|
|
|
232
225
|
[X_MODERNJS_RENDER]: 'client'
|
|
233
226
|
})
|
|
234
227
|
});
|
|
235
|
-
return csrRscRender(request, options);
|
|
228
|
+
else return csrRscRender(request, options);
|
|
236
229
|
}
|
|
237
230
|
export { createRender, matchRoute };
|
|
@@ -26,30 +26,59 @@ async function processCache({ request, key, requestHandler, requestHandlerOption
|
|
|
26
26
|
const reader = response.body.getReader();
|
|
27
27
|
const writer = stream.writable.getWriter();
|
|
28
28
|
let html = '';
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
let cancelled = false;
|
|
30
|
+
const cancel = async (reason)=>{
|
|
31
|
+
cancelled = true;
|
|
32
|
+
await reader.cancel(reason);
|
|
33
|
+
};
|
|
34
|
+
writer.closed.catch(cancel).catch(()=>{});
|
|
35
|
+
const onAbort = ()=>{
|
|
36
|
+
Promise.allSettled([
|
|
37
|
+
cancel(request.signal.reason),
|
|
38
|
+
writer.abort(request.signal.reason)
|
|
39
|
+
]);
|
|
40
|
+
};
|
|
41
|
+
request.signal.addEventListener('abort', onAbort, {
|
|
42
|
+
once: true
|
|
43
|
+
});
|
|
44
|
+
if (request.signal.aborted) onAbort();
|
|
45
|
+
const pumping = (async ()=>{
|
|
46
|
+
try {
|
|
47
|
+
for(;;){
|
|
48
|
+
const { done, value } = await reader.read();
|
|
49
|
+
if (cancelled) return;
|
|
50
|
+
if (done) break;
|
|
51
|
+
html += decoder.decode(value, {
|
|
52
|
+
stream: true
|
|
53
|
+
});
|
|
54
|
+
await writer.write(value);
|
|
55
|
+
}
|
|
56
|
+
html += decoder.decode();
|
|
57
|
+
await writer.close();
|
|
58
|
+
if (!cancelled && !ZERO_RENDER_LEVEL.test(html) && !NO_SSR_CACHE.test(html)) {
|
|
34
59
|
const cache = {
|
|
35
60
|
val: html,
|
|
36
|
-
cursor:
|
|
61
|
+
cursor: Date.now()
|
|
37
62
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
63
|
+
try {
|
|
64
|
+
await container.set(key, JSON.stringify(cache), {
|
|
65
|
+
ttl
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (onError) onError(error, 'render-cache');
|
|
69
|
+
else console.error(`[render-cache] set cache failed, key: ${key}`, error);
|
|
70
|
+
}
|
|
46
71
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
72
|
+
} catch (error) {
|
|
73
|
+
await Promise.allSettled([
|
|
74
|
+
cancel(error),
|
|
75
|
+
writer.abort(error)
|
|
76
|
+
]);
|
|
77
|
+
} finally{
|
|
78
|
+
request.signal.removeEventListener('abort', onAbort);
|
|
79
|
+
}
|
|
80
|
+
})();
|
|
81
|
+
pumping.catch(()=>{});
|
|
53
82
|
cacheStatus && response.headers.set(X_RENDER_CACHE, cacheStatus);
|
|
54
83
|
return new Response(stream.readable, {
|
|
55
84
|
status: response.status,
|
|
@@ -65,8 +94,8 @@ function computedKey(req, cacheControl) {
|
|
|
65
94
|
const { customKey } = cacheControl;
|
|
66
95
|
const defaultKey = '/' === pathname ? pathname : removeTailSlash(pathname);
|
|
67
96
|
if (!customKey) return defaultKey;
|
|
68
|
-
if ('string' == typeof customKey) return customKey;
|
|
69
|
-
return customKey(defaultKey);
|
|
97
|
+
else if ('string' == typeof customKey) return customKey;
|
|
98
|
+
else return customKey(defaultKey);
|
|
70
99
|
}
|
|
71
100
|
function shouldUseCache(request) {
|
|
72
101
|
const url = new URL(request.url);
|
|
@@ -77,7 +106,7 @@ function shouldUseCache(request) {
|
|
|
77
106
|
}
|
|
78
107
|
function matchCacheControl(cacheOption, req) {
|
|
79
108
|
if (!cacheOption || !req) return;
|
|
80
|
-
{
|
|
109
|
+
else {
|
|
81
110
|
if (isCacheControl(cacheOption)) return cacheOption;
|
|
82
111
|
if (isCacheOptionProvider(cacheOption)) return cacheOption(req);
|
|
83
112
|
const url = req.url;
|
|
@@ -116,7 +145,7 @@ async function getCacheResult(request, options) {
|
|
|
116
145
|
container,
|
|
117
146
|
cacheStatus: 'miss'
|
|
118
147
|
});
|
|
119
|
-
{
|
|
148
|
+
else {
|
|
120
149
|
const cache = JSON.parse(value);
|
|
121
150
|
const interval = Date.now() - cache.cursor;
|
|
122
151
|
if (interval <= maxAge) {
|
|
@@ -126,17 +155,16 @@ async function getCacheResult(request, options) {
|
|
|
126
155
|
[X_RENDER_CACHE]: cacheStatus
|
|
127
156
|
}
|
|
128
157
|
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
{
|
|
158
|
+
} else {
|
|
159
|
+
if (!(interval <= staleWhileRevalidate + maxAge)) return processCache({
|
|
160
|
+
key,
|
|
161
|
+
request,
|
|
162
|
+
requestHandler,
|
|
163
|
+
requestHandlerOptions,
|
|
164
|
+
ttl,
|
|
165
|
+
container,
|
|
166
|
+
cacheStatus: 'expired'
|
|
167
|
+
});
|
|
140
168
|
processCache({
|
|
141
169
|
key,
|
|
142
170
|
request,
|
|
@@ -146,6 +174,11 @@ async function getCacheResult(request, options) {
|
|
|
146
174
|
container
|
|
147
175
|
}).then(async (response)=>{
|
|
148
176
|
await response.text();
|
|
177
|
+
}).catch((error)=>{
|
|
178
|
+
try {
|
|
179
|
+
if (onError) onError(error, 'render-cache');
|
|
180
|
+
else console.error('[render-cache] revalidation failed', error);
|
|
181
|
+
} catch {}
|
|
149
182
|
});
|
|
150
183
|
const cacheStatus = 'stale';
|
|
151
184
|
return new Response(cache.val, {
|
|
@@ -106,7 +106,7 @@ function applyMiddlewares() {
|
|
|
106
106
|
if (middleware.before) {
|
|
107
107
|
const targetIndex = finalMiddlewares.findIndex((item)=>{
|
|
108
108
|
if (middleware.before?.includes(item.name)) return true;
|
|
109
|
-
return false;
|
|
109
|
+
else return false;
|
|
110
110
|
});
|
|
111
111
|
if (-1 !== targetIndex) finalMiddlewares.splice(targetIndex, 0, middleware);
|
|
112
112
|
else finalMiddlewares.push(middleware);
|
|
@@ -127,7 +127,7 @@ function applyMiddlewares() {
|
|
|
127
127
|
}
|
|
128
128
|
function handler2Handlers(handler) {
|
|
129
129
|
if (Array.isArray(handler)) return handler;
|
|
130
|
-
return [
|
|
130
|
+
else return [
|
|
131
131
|
handler
|
|
132
132
|
];
|
|
133
133
|
}
|
|
@@ -15,7 +15,7 @@ function transformResponse(response, transformCb) {
|
|
|
15
15
|
if (response.body) {
|
|
16
16
|
const stream = createTransformStream(async (before)=>{
|
|
17
17
|
if (Array.isArray(transformCb)) return transformCb.reduce(async (before, cb)=>cb(await before), Promise.resolve(before));
|
|
18
|
-
return transformCb(before);
|
|
18
|
+
else return transformCb(before);
|
|
19
19
|
});
|
|
20
20
|
response.body.pipeThrough(stream);
|
|
21
21
|
readable = stream.readable;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ServerRoute } from '@modern-js/types';
|
|
2
2
|
import type { HtmlNormalizedConfig, Middleware, OutputNormalizedConfig, ServerNormalizedConfig, ServerPlugin } from '../../../types/index.js';
|
|
3
3
|
export declare const serverStaticPlugin: () => ServerPlugin;
|
|
4
|
-
export type
|
|
4
|
+
export type PublicMiddlewareOptions = {
|
|
5
5
|
pwd: string;
|
|
6
6
|
routes: ServerRoute[];
|
|
7
7
|
};
|
|
8
|
-
export declare function createPublicMiddleware({ pwd, routes, }:
|
|
8
|
+
export declare function createPublicMiddleware({ pwd, routes, }: PublicMiddlewareOptions): Middleware;
|
|
9
9
|
export interface ServerStaticOptions {
|
|
10
10
|
pwd: string;
|
|
11
11
|
output: OutputNormalizedConfig;
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"modern",
|
|
16
16
|
"modern.js"
|
|
17
17
|
],
|
|
18
|
-
"version": "3.9.
|
|
18
|
+
"version": "3.9.3",
|
|
19
19
|
"types": "./dist/types/index.d.ts",
|
|
20
20
|
"main": "./dist/cjs/index.js",
|
|
21
21
|
"exports": {
|
|
@@ -70,20 +70,20 @@
|
|
|
70
70
|
"cloneable-readable": "^3.0.0",
|
|
71
71
|
"flatted": "^3.4.4",
|
|
72
72
|
"hono": "^4.11.7",
|
|
73
|
-
"ts-deepmerge": "
|
|
74
|
-
"@modern-js/plugin": "3.9.
|
|
75
|
-
"@modern-js/runtime-utils": "3.9.
|
|
76
|
-
"@modern-js/utils": "3.9.
|
|
73
|
+
"ts-deepmerge": "8.0.0",
|
|
74
|
+
"@modern-js/plugin": "3.9.3",
|
|
75
|
+
"@modern-js/runtime-utils": "3.9.3",
|
|
76
|
+
"@modern-js/utils": "3.9.3"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@rslib/core": "1.0.
|
|
79
|
+
"@rslib/core": "1.0.1",
|
|
80
80
|
"@types/cloneable-readable": "^2.0.3",
|
|
81
81
|
"@types/merge-deep": "^3.0.3",
|
|
82
82
|
"@types/node": "^20",
|
|
83
83
|
"http-proxy-middleware": "^2.0.10",
|
|
84
84
|
"typescript": "^5",
|
|
85
85
|
"@modern-js/rslib": "2.68.10",
|
|
86
|
-
"@modern-js/types": "3.9.
|
|
86
|
+
"@modern-js/types": "3.9.3",
|
|
87
87
|
"@scripts/rstest-config": "2.66.0"
|
|
88
88
|
},
|
|
89
89
|
"sideEffects": false,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
var __webpack_modules__ = {};
|
|
2
|
-
var __webpack_module_cache__ = {};
|
|
3
|
-
function __webpack_require__(moduleId) {
|
|
4
|
-
var cachedModule = __webpack_module_cache__[moduleId];
|
|
5
|
-
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
6
|
-
var module = __webpack_module_cache__[moduleId] = {
|
|
7
|
-
exports: {}
|
|
8
|
-
};
|
|
9
|
-
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
10
|
-
return module.exports;
|
|
11
|
-
}
|
|
12
|
-
__webpack_require__.m = __webpack_modules__;
|
|
13
|
-
(()=>{
|
|
14
|
-
__webpack_require__.add = function(modules) {
|
|
15
|
-
Object.assign(__webpack_require__.m, modules);
|
|
16
|
-
};
|
|
17
|
-
})();
|
|
18
|
-
export { __webpack_require__ };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import "node:module";
|
|
2
|
-
var __webpack_modules__ = {};
|
|
3
|
-
var __webpack_module_cache__ = {};
|
|
4
|
-
function __webpack_require__(moduleId) {
|
|
5
|
-
var cachedModule = __webpack_module_cache__[moduleId];
|
|
6
|
-
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
7
|
-
var module = __webpack_module_cache__[moduleId] = {
|
|
8
|
-
exports: {}
|
|
9
|
-
};
|
|
10
|
-
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
11
|
-
return module.exports;
|
|
12
|
-
}
|
|
13
|
-
__webpack_require__.m = __webpack_modules__;
|
|
14
|
-
(()=>{
|
|
15
|
-
__webpack_require__.add = function(modules) {
|
|
16
|
-
Object.assign(__webpack_require__.m, modules);
|
|
17
|
-
};
|
|
18
|
-
})();
|
|
19
|
-
export { __webpack_require__ };
|