@modern-js/prod-server 2.47.0 → 2.48.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.
@@ -89,7 +89,7 @@ const render = async (ctx, renderOptions, runner) => {
89
89
  runner.extendSSRContext(context);
90
90
  const bundleJSContent = await Promise.resolve(require(bundleJS));
91
91
  const serverRender = bundleJSContent[import_utils.SERVER_RENDER_FUNCTION_NAME];
92
- const content = await (0, import_ssrCache.ssrCache)(ctx.req, serverRender, context);
92
+ const { data: content, status: cacheStatus } = await (0, import_ssrCache.ssrCache)(ctx.req, serverRender, context);
93
93
  const { url, status = 302 } = context.redirection;
94
94
  if (url) {
95
95
  return {
@@ -99,10 +99,13 @@ const render = async (ctx, renderOptions, runner) => {
99
99
  redirect: true
100
100
  };
101
101
  }
102
+ const headers = {};
103
+ cacheStatus && (headers["x-render-cache"] = cacheStatus);
102
104
  if (typeof content === "string") {
103
105
  return {
104
106
  content: (0, import_utils2.injectServerData)(content, ctx),
105
- contentType: import_utils.mime.contentType("html")
107
+ contentType: import_utils.mime.contentType("html"),
108
+ headers
106
109
  };
107
110
  } else {
108
111
  let contentStream = (0, import_utils2.injectServerDataStream)(content, ctx);
@@ -116,7 +119,8 @@ const render = async (ctx, renderOptions, runner) => {
116
119
  return {
117
120
  content: "",
118
121
  contentStream,
119
- contentType: import_utils.mime.contentType("html")
122
+ contentType: import_utils.mime.contentType("html"),
123
+ headers
120
124
  };
121
125
  }
122
126
  };
@@ -35,9 +35,13 @@ async function ssrCache(req, render, ssrContext) {
35
35
  } else {
36
36
  const renderResult = await render(ssrContext);
37
37
  if (!renderResult) {
38
- return "";
38
+ return {
39
+ data: ""
40
+ };
39
41
  } else if (typeof renderResult === "string") {
40
- return renderResult;
42
+ return {
43
+ data: renderResult
44
+ };
41
45
  } else {
42
46
  const stream = new import_stream.Transform({
43
47
  write(chunk, _, callback) {
@@ -45,7 +49,10 @@ async function ssrCache(req, render, ssrContext) {
45
49
  callback();
46
50
  }
47
51
  });
48
- return renderResult(stream);
52
+ const data = await renderResult(stream);
53
+ return {
54
+ data
55
+ };
49
56
  }
50
57
  }
51
58
  }
@@ -33,21 +33,29 @@ class CacheManager {
33
33
  const cache = JSON.parse(value);
34
34
  const interval = Date.now() - cache.cursor;
35
35
  if (interval <= maxAge) {
36
- return cache.val;
36
+ return {
37
+ data: cache.val,
38
+ status: "hit"
39
+ };
37
40
  } else if (interval <= staleWhileRevalidate + maxAge) {
38
41
  this.processCache(key, render, ssrContext, ttl);
39
- return cache.val;
42
+ return {
43
+ data: cache.val,
44
+ status: "stale"
45
+ };
40
46
  } else {
41
- return this.processCache(key, render, ssrContext, ttl);
47
+ return this.processCache(key, render, ssrContext, ttl, "expired");
42
48
  }
43
49
  } else {
44
- return this.processCache(key, render, ssrContext, ttl);
50
+ return this.processCache(key, render, ssrContext, ttl, "miss");
45
51
  }
46
52
  }
47
- async processCache(key, render, ssrContext, ttl) {
53
+ async processCache(key, render, ssrContext, ttl, status) {
48
54
  const renderResult = await render(ssrContext);
49
55
  if (!renderResult) {
50
- return "";
56
+ return {
57
+ data: ""
58
+ };
51
59
  } else if (typeof renderResult === "string") {
52
60
  const current = Date.now();
53
61
  const cache = {
@@ -57,7 +65,10 @@ class CacheManager {
57
65
  await this.container.set(key, JSON.stringify(cache), {
58
66
  ttl
59
67
  });
60
- return renderResult;
68
+ return {
69
+ data: renderResult,
70
+ status
71
+ };
61
72
  } else {
62
73
  let html = "";
63
74
  const stream = new import_stream.Transform({
@@ -77,7 +88,11 @@ class CacheManager {
77
88
  ttl
78
89
  });
79
90
  });
80
- return renderResult(stream);
91
+ const readable = await renderResult(stream);
92
+ return {
93
+ data: readable,
94
+ status
95
+ };
81
96
  }
82
97
  }
83
98
  computedKey(req, cacheControl) {
@@ -360,7 +360,13 @@ class ModernServer {
360
360
  if (!renderResult) {
361
361
  return;
362
362
  }
363
- const { contentStream: responseStream } = renderResult;
363
+ const { contentStream: responseStream, headers } = renderResult;
364
+ if (headers) {
365
+ for (const name in headers) {
366
+ const value = headers[name];
367
+ res.setHeader(name, value);
368
+ }
369
+ }
364
370
  let { content: response } = renderResult;
365
371
  if (route.entryName && responseStream) {
366
372
  responseStream.pipe(res);
@@ -10,7 +10,7 @@ import { injectServerDataStream, injectServerData } from "./utils";
10
10
  import { ssrCache } from "./ssrCache";
11
11
  var render = function() {
12
12
  var _ref = _async_to_generator(function(ctx, renderOptions, runner) {
13
- var _ctx_res, distDir, route, template, staticGenerate, _renderOptions_enableUnsafeCtx, enableUnsafeCtx, nonce, urlPath, bundle, entryName, bundleJS, loadableUri, loadableStats, routesManifestUri, routeManifest, isSpider, context, bundleJSContent, serverRender, content, _context_redirection, url, _context_redirection_status, status, contentStream, afterStreamingRenderContext;
13
+ var _ctx_res, distDir, route, template, staticGenerate, _renderOptions_enableUnsafeCtx, enableUnsafeCtx, nonce, urlPath, bundle, entryName, bundleJS, loadableUri, loadableStats, routesManifestUri, routeManifest, isSpider, context, bundleJSContent, serverRender, _ref2, content, cacheStatus, _context_redirection, url, _context_redirection_status, status, headers, contentStream, afterStreamingRenderContext;
14
14
  return _ts_generator(this, function(_state) {
15
15
  switch (_state.label) {
16
16
  case 0:
@@ -72,7 +72,7 @@ var render = function() {
72
72
  ssrCache(ctx.req, serverRender, context)
73
73
  ];
74
74
  case 2:
75
- content = _state.sent();
75
+ _ref2 = _state.sent(), content = _ref2.data, cacheStatus = _ref2.status;
76
76
  _context_redirection = context.redirection, url = _context_redirection.url, _context_redirection_status = _context_redirection.status, status = _context_redirection_status === void 0 ? 302 : _context_redirection_status;
77
77
  if (url) {
78
78
  return [
@@ -85,12 +85,15 @@ var render = function() {
85
85
  }
86
86
  ];
87
87
  }
88
+ headers = {};
89
+ cacheStatus && (headers["x-render-cache"] = cacheStatus);
88
90
  if (typeof content === "string") {
89
91
  return [
90
92
  2,
91
93
  {
92
94
  content: injectServerData(content, ctx),
93
- contentType: mime.contentType("html")
95
+ contentType: mime.contentType("html"),
96
+ headers
94
97
  }
95
98
  ];
96
99
  } else {
@@ -110,7 +113,8 @@ var render = function() {
110
113
  {
111
114
  content: "",
112
115
  contentStream,
113
- contentType: mime.contentType("html")
116
+ contentType: mime.contentType("html"),
117
+ headers
114
118
  }
115
119
  ];
116
120
  }
@@ -11,7 +11,7 @@ function ssrCache(req, render, ssrContext) {
11
11
  }
12
12
  function _ssrCache() {
13
13
  _ssrCache = _async_to_generator(function(req, render, ssrContext) {
14
- var customContainer, cacheOption, cacheControl, cacheManager, renderResult, stream;
14
+ var customContainer, cacheOption, cacheControl, cacheManager, renderResult, stream, data;
15
15
  return _ts_generator(this, function(_state) {
16
16
  switch (_state.label) {
17
17
  case 0:
@@ -39,30 +39,49 @@ function _ssrCache() {
39
39
  ];
40
40
  case 3:
41
41
  renderResult = _state.sent();
42
- if (!renderResult) {
42
+ if (!!renderResult)
43
43
  return [
44
- 2,
45
- ""
46
- ];
47
- } else if (typeof renderResult === "string") {
48
- return [
49
- 2,
50
- renderResult
44
+ 3,
45
+ 4
51
46
  ];
52
- } else {
53
- stream = new Transform({
54
- write: function write(chunk, _, callback) {
55
- this.push(chunk);
56
- callback();
57
- }
58
- });
47
+ return [
48
+ 2,
49
+ {
50
+ data: ""
51
+ }
52
+ ];
53
+ case 4:
54
+ if (!(typeof renderResult === "string"))
59
55
  return [
60
- 2,
61
- renderResult(stream)
56
+ 3,
57
+ 5
62
58
  ];
63
- }
64
- _state.label = 4;
65
- case 4:
59
+ return [
60
+ 2,
61
+ {
62
+ data: renderResult
63
+ }
64
+ ];
65
+ case 5:
66
+ stream = new Transform({
67
+ write: function write(chunk, _, callback) {
68
+ this.push(chunk);
69
+ callback();
70
+ }
71
+ });
72
+ return [
73
+ 4,
74
+ renderResult(stream)
75
+ ];
76
+ case 6:
77
+ data = _state.sent();
78
+ return [
79
+ 2,
80
+ {
81
+ data
82
+ }
83
+ ];
84
+ case 7:
66
85
  return [
67
86
  2
68
87
  ];
@@ -37,24 +37,30 @@ var CacheManager = /* @__PURE__ */ function() {
37
37
  if (interval <= maxAge) {
38
38
  return [
39
39
  2,
40
- cache.val
40
+ {
41
+ data: cache.val,
42
+ status: "hit"
43
+ }
41
44
  ];
42
45
  } else if (interval <= staleWhileRevalidate + maxAge) {
43
46
  _this.processCache(key, render, ssrContext, ttl);
44
47
  return [
45
48
  2,
46
- cache.val
49
+ {
50
+ data: cache.val,
51
+ status: "stale"
52
+ }
47
53
  ];
48
54
  } else {
49
55
  return [
50
56
  2,
51
- _this.processCache(key, render, ssrContext, ttl)
57
+ _this.processCache(key, render, ssrContext, ttl, "expired")
52
58
  ];
53
59
  }
54
60
  } else {
55
61
  return [
56
62
  2,
57
- _this.processCache(key, render, ssrContext, ttl)
63
+ _this.processCache(key, render, ssrContext, ttl, "miss")
58
64
  ];
59
65
  }
60
66
  return [
@@ -67,10 +73,10 @@ var CacheManager = /* @__PURE__ */ function() {
67
73
  },
68
74
  {
69
75
  key: "processCache",
70
- value: function processCache(key, render, ssrContext, ttl) {
76
+ value: function processCache(key, render, ssrContext, ttl, status) {
71
77
  var _this = this;
72
78
  return _async_to_generator(function() {
73
- var renderResult, current, cache, html, stream;
79
+ var renderResult, current, cache, html, stream, readable;
74
80
  return _ts_generator(this, function(_state) {
75
81
  switch (_state.label) {
76
82
  case 0:
@@ -87,7 +93,9 @@ var CacheManager = /* @__PURE__ */ function() {
87
93
  ];
88
94
  return [
89
95
  2,
90
- ""
96
+ {
97
+ data: ""
98
+ }
91
99
  ];
92
100
  case 2:
93
101
  if (!(typeof renderResult === "string"))
@@ -110,7 +118,10 @@ var CacheManager = /* @__PURE__ */ function() {
110
118
  _state.sent();
111
119
  return [
112
120
  2,
113
- renderResult
121
+ {
122
+ data: renderResult,
123
+ status
124
+ }
114
125
  ];
115
126
  case 4:
116
127
  html = "";
@@ -132,10 +143,19 @@ var CacheManager = /* @__PURE__ */ function() {
132
143
  });
133
144
  });
134
145
  return [
135
- 2,
146
+ 4,
136
147
  renderResult(stream)
137
148
  ];
138
149
  case 5:
150
+ readable = _state.sent();
151
+ return [
152
+ 2,
153
+ {
154
+ data: readable,
155
+ status
156
+ }
157
+ ];
158
+ case 6:
139
159
  return [
140
160
  2
141
161
  ];
@@ -660,7 +660,7 @@ var ModernServer = /* @__PURE__ */ function() {
660
660
  function routeHandler(context) {
661
661
  var _this = this;
662
662
  return _async_to_generator(function() {
663
- var res, reporter, matched, end, route, afterMatchContext, end1, cost, _afterMatchContext_router, current, url, status, matched1, middlewareContext, end2, cost1, renderResult, responseStream, response, afterRenderContext, end3, cost2;
663
+ var res, reporter, matched, end, route, afterMatchContext, end1, cost, _afterMatchContext_router, current, url, status, matched1, middlewareContext, end2, cost1, renderResult, responseStream, headers, name, value, response, afterRenderContext, end3, cost2;
664
664
  return _ts_generator(this, function(_state) {
665
665
  switch (_state.label) {
666
666
  case 0:
@@ -777,7 +777,13 @@ var ModernServer = /* @__PURE__ */ function() {
777
777
  2
778
778
  ];
779
779
  }
780
- responseStream = renderResult.contentStream;
780
+ responseStream = renderResult.contentStream, headers = renderResult.headers;
781
+ if (headers) {
782
+ for (var name2 in headers) {
783
+ value = headers[name2];
784
+ res.setHeader(name2, value);
785
+ }
786
+ }
781
787
  response = renderResult.content;
782
788
  if (route.entryName && responseStream) {
783
789
  responseStream.pipe(res);
@@ -56,7 +56,7 @@ const render = async (ctx, renderOptions, runner) => {
56
56
  runner.extendSSRContext(context);
57
57
  const bundleJSContent = await Promise.resolve(require(bundleJS));
58
58
  const serverRender = bundleJSContent[SERVER_RENDER_FUNCTION_NAME];
59
- const content = await ssrCache(ctx.req, serverRender, context);
59
+ const { data: content, status: cacheStatus } = await ssrCache(ctx.req, serverRender, context);
60
60
  const { url, status = 302 } = context.redirection;
61
61
  if (url) {
62
62
  return {
@@ -66,10 +66,13 @@ const render = async (ctx, renderOptions, runner) => {
66
66
  redirect: true
67
67
  };
68
68
  }
69
+ const headers = {};
70
+ cacheStatus && (headers["x-render-cache"] = cacheStatus);
69
71
  if (typeof content === "string") {
70
72
  return {
71
73
  content: injectServerData(content, ctx),
72
- contentType: mime.contentType("html")
74
+ contentType: mime.contentType("html"),
75
+ headers
73
76
  };
74
77
  } else {
75
78
  let contentStream = injectServerDataStream(content, ctx);
@@ -83,7 +86,8 @@ const render = async (ctx, renderOptions, runner) => {
83
86
  return {
84
87
  content: "",
85
88
  contentStream,
86
- contentType: mime.contentType("html")
89
+ contentType: mime.contentType("html"),
90
+ headers
87
91
  };
88
92
  }
89
93
  };
@@ -12,9 +12,13 @@ async function ssrCache(req, render, ssrContext) {
12
12
  } else {
13
13
  const renderResult = await render(ssrContext);
14
14
  if (!renderResult) {
15
- return "";
15
+ return {
16
+ data: ""
17
+ };
16
18
  } else if (typeof renderResult === "string") {
17
- return renderResult;
19
+ return {
20
+ data: renderResult
21
+ };
18
22
  } else {
19
23
  const stream = new Transform({
20
24
  write(chunk, _, callback) {
@@ -22,7 +26,10 @@ async function ssrCache(req, render, ssrContext) {
22
26
  callback();
23
27
  }
24
28
  });
25
- return renderResult(stream);
29
+ const data = await renderResult(stream);
30
+ return {
31
+ data
32
+ };
26
33
  }
27
34
  }
28
35
  }
@@ -10,21 +10,29 @@ class CacheManager {
10
10
  const cache = JSON.parse(value);
11
11
  const interval = Date.now() - cache.cursor;
12
12
  if (interval <= maxAge) {
13
- return cache.val;
13
+ return {
14
+ data: cache.val,
15
+ status: "hit"
16
+ };
14
17
  } else if (interval <= staleWhileRevalidate + maxAge) {
15
18
  this.processCache(key, render, ssrContext, ttl);
16
- return cache.val;
19
+ return {
20
+ data: cache.val,
21
+ status: "stale"
22
+ };
17
23
  } else {
18
- return this.processCache(key, render, ssrContext, ttl);
24
+ return this.processCache(key, render, ssrContext, ttl, "expired");
19
25
  }
20
26
  } else {
21
- return this.processCache(key, render, ssrContext, ttl);
27
+ return this.processCache(key, render, ssrContext, ttl, "miss");
22
28
  }
23
29
  }
24
- async processCache(key, render, ssrContext, ttl) {
30
+ async processCache(key, render, ssrContext, ttl, status) {
25
31
  const renderResult = await render(ssrContext);
26
32
  if (!renderResult) {
27
- return "";
33
+ return {
34
+ data: ""
35
+ };
28
36
  } else if (typeof renderResult === "string") {
29
37
  const current = Date.now();
30
38
  const cache = {
@@ -34,7 +42,10 @@ class CacheManager {
34
42
  await this.container.set(key, JSON.stringify(cache), {
35
43
  ttl
36
44
  });
37
- return renderResult;
45
+ return {
46
+ data: renderResult,
47
+ status
48
+ };
38
49
  } else {
39
50
  let html = "";
40
51
  const stream = new Transform({
@@ -54,7 +65,11 @@ class CacheManager {
54
65
  ttl
55
66
  });
56
67
  });
57
- return renderResult(stream);
68
+ const readable = await renderResult(stream);
69
+ return {
70
+ data: readable,
71
+ status
72
+ };
58
73
  }
59
74
  }
60
75
  computedKey(req, cacheControl) {
@@ -327,7 +327,13 @@ class ModernServer {
327
327
  if (!renderResult) {
328
328
  return;
329
329
  }
330
- const { contentStream: responseStream } = renderResult;
330
+ const { contentStream: responseStream, headers } = renderResult;
331
+ if (headers) {
332
+ for (const name in headers) {
333
+ const value = headers[name];
334
+ res.setHeader(name, value);
335
+ }
336
+ }
331
337
  let { content: response } = renderResult;
332
338
  if (route.entryName && responseStream) {
333
339
  responseStream.pipe(res);
@@ -1,7 +1,6 @@
1
- /// <reference types="node" />
2
1
  /// <reference types="node/http" />
3
2
  /// <reference types="dist/types/type" />
4
3
  import { IncomingMessage } from 'http';
5
- import { type Readable } from 'stream';
6
4
  import { RenderFunction, SSRServerContext } from '../type';
7
- export declare function ssrCache(req: IncomingMessage, render: RenderFunction, ssrContext: SSRServerContext): Promise<string | Readable>;
5
+ import { CacheResult } from './manager';
6
+ export declare function ssrCache(req: IncomingMessage, render: RenderFunction, ssrContext: SSRServerContext): Promise<CacheResult>;
@@ -5,10 +5,16 @@ import { IncomingMessage } from 'http';
5
5
  import { Readable } from 'stream';
6
6
  import { CacheControl, Container } from '@modern-js/types';
7
7
  import { RenderFunction, SSRServerContext } from '../type';
8
+ type CacheStatus = 'hit' | 'stale' | 'expired' | 'miss';
9
+ export type CacheResult = {
10
+ data: string | Readable;
11
+ status?: CacheStatus;
12
+ };
8
13
  export declare class CacheManager {
9
14
  private container;
10
15
  constructor(container: Container<string, string>);
11
- getCacheResult(req: IncomingMessage, cacheControl: CacheControl, render: RenderFunction, ssrContext: SSRServerContext): Promise<string | Readable>;
16
+ getCacheResult(req: IncomingMessage, cacheControl: CacheControl, render: RenderFunction, ssrContext: SSRServerContext): Promise<CacheResult>;
12
17
  private processCache;
13
18
  private computedKey;
14
19
  }
20
+ export {};
@@ -49,6 +49,7 @@ export type RenderResult = {
49
49
  contentType: string;
50
50
  contentStream?: Readable;
51
51
  statusCode?: number;
52
+ headers?: Record<string, string>;
52
53
  redirect?: boolean;
53
54
  };
54
55
  export type ConfWithBFF = {
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.47.0",
18
+ "version": "2.48.0",
19
19
  "jsnext:source": "./src/index.ts",
20
20
  "types": "./dist/types/index.d.ts",
21
21
  "main": "./dist/cjs/index.js",
@@ -74,10 +74,10 @@
74
74
  "node-html-parser": "^6.1.5",
75
75
  "path-to-regexp": "^6.2.0",
76
76
  "serve-static": "^1.14.1",
77
- "@modern-js/utils": "2.47.0",
78
- "@modern-js/plugin": "2.47.0",
79
- "@modern-js/runtime-utils": "2.47.0",
80
- "@modern-js/server-core": "2.47.0"
77
+ "@modern-js/plugin": "2.48.0",
78
+ "@modern-js/utils": "2.48.0",
79
+ "@modern-js/server-core": "2.48.0",
80
+ "@modern-js/runtime-utils": "2.48.0"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@types/cookie": "0.5.1",
@@ -95,9 +95,9 @@
95
95
  "portfinder": "^1.0.28",
96
96
  "typescript": "^5",
97
97
  "ws": "^8.13.0",
98
- "@modern-js/types": "2.47.0",
99
- "@scripts/build": "2.47.0",
100
- "@scripts/jest-config": "2.47.0"
98
+ "@modern-js/types": "2.48.0",
99
+ "@scripts/build": "2.48.0",
100
+ "@scripts/jest-config": "2.48.0"
101
101
  },
102
102
  "sideEffects": false,
103
103
  "publishConfig": {