@modern-js/prod-server 2.27.0 → 2.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/cjs/index.js +4 -0
  3. package/dist/cjs/libs/context/context.js +10 -4
  4. package/dist/cjs/libs/hook-api/index.js +2 -1
  5. package/dist/cjs/libs/hook-api/index.worker.js +2 -1
  6. package/dist/cjs/libs/render/cache/__tests__/cache.test.js +12 -7
  7. package/dist/cjs/libs/render/cache/index.js +2 -1
  8. package/dist/cjs/libs/render/cache/spr.js +2 -1
  9. package/dist/cjs/libs/render/index.js +12 -3
  10. package/dist/cjs/libs/render/reader.js +2 -1
  11. package/dist/cjs/libs/render/ssr.js +3 -20
  12. package/dist/cjs/libs/reporter.js +22 -0
  13. package/dist/cjs/libs/route/matcher.js +2 -2
  14. package/dist/cjs/libs/serverTiming.js +27 -0
  15. package/dist/cjs/server/index.js +6 -4
  16. package/dist/cjs/server/modernServer.js +44 -16
  17. package/dist/cjs/utils.js +33 -0
  18. package/dist/cjs/workerServer.js +15 -6
  19. package/dist/esm/index.js +1 -0
  20. package/dist/esm/libs/context/context.js +8 -2
  21. package/dist/esm/libs/hook-api/index.js +2 -1
  22. package/dist/esm/libs/hook-api/index.worker.js +2 -1
  23. package/dist/esm/libs/render/cache/__tests__/cache.test.js +12 -12
  24. package/dist/esm/libs/render/cache/index.js +2 -2
  25. package/dist/esm/libs/render/cache/spr.js +2 -2
  26. package/dist/esm/libs/render/index.js +12 -3
  27. package/dist/esm/libs/render/reader.js +2 -2
  28. package/dist/esm/libs/render/ssr.js +6 -28
  29. package/dist/esm/libs/reporter.js +12 -0
  30. package/dist/esm/libs/route/matcher.js +2 -2
  31. package/dist/esm/libs/serverTiming.js +27 -0
  32. package/dist/esm/renderHtml.js +6 -6
  33. package/dist/esm/server/index.js +6 -4
  34. package/dist/esm/server/modernServer.js +84 -44
  35. package/dist/esm/server/modernServerSplit.js +6 -6
  36. package/dist/esm/utils.js +57 -0
  37. package/dist/esm/workerServer.js +14 -5
  38. package/dist/esm-node/index.js +1 -0
  39. package/dist/esm-node/libs/context/context.js +8 -2
  40. package/dist/esm-node/libs/hook-api/index.js +2 -1
  41. package/dist/esm-node/libs/hook-api/index.worker.js +2 -1
  42. package/dist/esm-node/libs/render/cache/__tests__/cache.test.js +12 -7
  43. package/dist/esm-node/libs/render/cache/index.js +2 -1
  44. package/dist/esm-node/libs/render/cache/spr.js +2 -1
  45. package/dist/esm-node/libs/render/index.js +12 -3
  46. package/dist/esm-node/libs/render/reader.js +2 -1
  47. package/dist/esm-node/libs/render/ssr.js +3 -20
  48. package/dist/esm-node/libs/reporter.js +12 -0
  49. package/dist/esm-node/libs/route/matcher.js +2 -2
  50. package/dist/esm-node/libs/serverTiming.js +17 -0
  51. package/dist/esm-node/server/index.js +6 -4
  52. package/dist/esm-node/server/modernServer.js +45 -17
  53. package/dist/esm-node/utils.js +30 -0
  54. package/dist/esm-node/workerServer.js +15 -6
  55. package/dist/types/index.d.ts +1 -0
  56. package/dist/types/libs/context/context.d.ts +5 -2
  57. package/dist/types/libs/hook-api/index.worker.d.ts +2 -1
  58. package/dist/types/libs/render/index.d.ts +13 -18
  59. package/dist/types/libs/reporter.d.ts +2 -0
  60. package/dist/types/libs/serverTiming.d.ts +12 -0
  61. package/dist/types/server/modernServer.d.ts +6 -4
  62. package/dist/types/type.d.ts +1 -0
  63. package/dist/types/utils.d.ts +3 -2
  64. package/package.json +8 -8
@@ -8,10 +8,11 @@ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
8
8
  import { createServer } from "http";
9
9
  import path from "path";
10
10
  import { fs, isPromise, isWebOnly, mime, ROUTE_SPEC_FILE } from "@modern-js/utils";
11
+ import { time } from "@modern-js/utils/universal/time";
11
12
  import { RouteMatchManager } from "../libs/route";
12
13
  import { createRenderHandler } from "../libs/render";
13
14
  import { createStaticFileHandler, faviconFallbackHandler } from "../libs/serveFile";
14
- import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect } from "../utils";
15
+ import { createErrorDocument, createMiddlewareCollecter, getStaticReg, mergeExtension, noop, debug, isRedirect, bodyParser } from "../utils";
15
16
  import * as reader from "../libs/render/reader";
16
17
  import { createProxyHandler } from "../libs/proxy";
17
18
  import { createContext } from "../libs/context";
@@ -23,6 +24,7 @@ export var ModernServer = /* @__PURE__ */ function() {
23
24
  function ModernServer2(param) {
24
25
  var pwd = param.pwd, config = param.config, routes = param.routes, staticGenerate = param.staticGenerate, logger = param.logger, metrics = param.metrics, runMode = param.runMode, proxyTarget = param.proxyTarget, appContext = param.appContext;
25
26
  _class_call_check(this, ModernServer2);
27
+ var _appContext;
26
28
  _define_property(this, "pwd", void 0);
27
29
  _define_property(this, "distDir", void 0);
28
30
  _define_property(this, "workDir", void 0);
@@ -37,13 +39,13 @@ export var ModernServer = /* @__PURE__ */ function() {
37
39
  _define_property(this, "reader", reader);
38
40
  _define_property(this, "proxyTarget", void 0);
39
41
  _define_property(this, "routeRenderHandler", void 0);
42
+ _define_property(this, "staticGenerate", void 0);
43
+ _define_property(this, "metaName", void 0);
40
44
  _define_property(this, "loaderHandler", null);
41
45
  _define_property(this, "frameWebHandler", null);
42
46
  _define_property(this, "frameAPIHandler", null);
43
47
  _define_property(this, "proxyHandler", null);
44
48
  _define_property(this, "_handler", void 0);
45
- _define_property(this, "staticGenerate", void 0);
46
- _define_property(this, "metaName", void 0);
47
49
  require("ignore-styles");
48
50
  this.pwd = pwd;
49
51
  this.distDir = path.resolve(pwd, config.output.path || "dist");
@@ -57,7 +59,7 @@ export var ModernServer = /* @__PURE__ */ function() {
57
59
  this.proxyTarget = proxyTarget;
58
60
  this.staticGenerate = staticGenerate || false;
59
61
  this.runMode = runMode || RUN_MODE.FULL;
60
- this.metaName = appContext === null || appContext === void 0 ? void 0 : appContext.metaName;
62
+ this.metaName = (_appContext = appContext) === null || _appContext === void 0 ? void 0 : _appContext.metaName;
61
63
  }
62
64
  _create_class(ModernServer2, [
63
65
  {
@@ -67,12 +69,12 @@ export var ModernServer = /* @__PURE__ */ function() {
67
69
  function onInit(runner, app) {
68
70
  var _this = this;
69
71
  return _async_to_generator(function() {
70
- var _conf_bff, _this_conf_server, _conf_security, _this_conf_output, distDir, staticGenerate, conf, metaName, usageRoutes, ssrConfig, forceCSR;
72
+ var _conf_bff, _app, _this_conf_output, distDir, conf, usageRoutes;
71
73
  return _ts_generator(this, function(_state) {
72
74
  switch (_state.label) {
73
75
  case 0:
74
76
  _this.runner = runner;
75
- distDir = _this.distDir, staticGenerate = _this.staticGenerate, conf = _this.conf, metaName = _this.metaName;
77
+ distDir = _this.distDir, conf = _this.conf;
76
78
  _this.initReader();
77
79
  debug("final server conf", _this.conf);
78
80
  _this.proxyHandler = createProxyHandler((_conf_bff = conf.bff) === null || _conf_bff === void 0 ? void 0 : _conf_bff.proxy);
@@ -81,7 +83,7 @@ export var ModernServer = /* @__PURE__ */ function() {
81
83
  _this.addHandler(handler);
82
84
  });
83
85
  }
84
- app === null || app === void 0 ? void 0 : app.on("close", function() {
86
+ (_app = app) === null || _app === void 0 ? void 0 : _app.on("close", function() {
85
87
  _this.reader.close();
86
88
  });
87
89
  usageRoutes = _this.filterRoutes(_this.getRoutes());
@@ -99,15 +101,7 @@ export var ModernServer = /* @__PURE__ */ function() {
99
101
  ];
100
102
  case 2:
101
103
  _state.sent();
102
- ssrConfig = (_this_conf_server = _this.conf.server) === null || _this_conf_server === void 0 ? void 0 : _this_conf_server.ssr;
103
- forceCSR = typeof ssrConfig === "object" ? ssrConfig.forceCSR : false;
104
- _this.routeRenderHandler = createRenderHandler({
105
- distDir: distDir,
106
- staticGenerate: staticGenerate,
107
- forceCSR: forceCSR,
108
- nonce: (_conf_security = conf.security) === null || _conf_security === void 0 ? void 0 : _conf_security.nonce,
109
- metaName: metaName
110
- });
104
+ _this.routeRenderHandler = _this.getRenderHandler();
111
105
  return [
112
106
  4,
113
107
  _this.setupBeforeProdMiddleware()
@@ -127,6 +121,22 @@ export var ModernServer = /* @__PURE__ */ function() {
127
121
  }
128
122
  )
129
123
  },
124
+ {
125
+ key: "getRenderHandler",
126
+ value: function getRenderHandler() {
127
+ var _this_conf_server, _conf_security;
128
+ var _this = this, distDir = _this.distDir, staticGenerate = _this.staticGenerate, conf = _this.conf, metaName = _this.metaName;
129
+ var ssrConfig = (_this_conf_server = this.conf.server) === null || _this_conf_server === void 0 ? void 0 : _this_conf_server.ssr;
130
+ var forceCSR = typeof ssrConfig === "object" ? ssrConfig.forceCSR : false;
131
+ return createRenderHandler({
132
+ distDir: distDir,
133
+ staticGenerate: staticGenerate,
134
+ forceCSR: forceCSR,
135
+ nonce: (_conf_security = conf.security) === null || _conf_security === void 0 ? void 0 : _conf_security.nonce,
136
+ metaName: metaName
137
+ });
138
+ }
139
+ },
130
140
  {
131
141
  key: "onRepack",
132
142
  value: (
@@ -155,7 +165,9 @@ export var ModernServer = /* @__PURE__ */ function() {
155
165
  case 0:
156
166
  req.logger = req.logger || _this.logger;
157
167
  req.metrics = req.metrics || _this.metrics;
158
- context = createContext(req, res);
168
+ context = createContext(req, res, {
169
+ metaName: _this.metaName
170
+ });
159
171
  matched = _this.router.match(url || context.path);
160
172
  if (!matched) {
161
173
  return [
@@ -418,13 +430,13 @@ export var ModernServer = /* @__PURE__ */ function() {
418
430
  value: function prepareAPIHandler(extension) {
419
431
  var _this = this;
420
432
  return _async_to_generator(function() {
421
- var workDir, runner, conf, bff, prefix, webOnly;
433
+ var _bff, _bff1, workDir, runner, conf, bff, prefix, webOnly;
422
434
  return _ts_generator(this, function(_state) {
423
435
  switch (_state.label) {
424
436
  case 0:
425
437
  workDir = _this.workDir, runner = _this.runner, conf = _this.conf;
426
438
  bff = conf.bff;
427
- prefix = (bff === null || bff === void 0 ? void 0 : bff.prefix) || "/api";
439
+ prefix = ((_bff = bff) === null || _bff === void 0 ? void 0 : _bff.prefix) || "/api";
428
440
  return [
429
441
  4,
430
442
  isWebOnly()
@@ -446,7 +458,7 @@ export var ModernServer = /* @__PURE__ */ function() {
446
458
  pwd: workDir,
447
459
  config: extension,
448
460
  prefix: Array.isArray(prefix) ? prefix[0] : prefix,
449
- httpMethodDecider: bff === null || bff === void 0 ? void 0 : bff.httpMethodDecider,
461
+ httpMethodDecider: (_bff1 = bff) === null || _bff1 === void 0 ? void 0 : _bff1.httpMethodDecider,
450
462
  render: _this.render.bind(_this)
451
463
  }, {
452
464
  onLast: function() {
@@ -657,11 +669,11 @@ export var ModernServer = /* @__PURE__ */ function() {
657
669
  function routeHandler(context) {
658
670
  var _this = this;
659
671
  return _async_to_generator(function() {
660
- var res, matched, route, afterMatchContext, _afterMatchContext_router, current, url, status, matched1, middlewareContext, renderResult, responseStream, response, afterRenderContext;
672
+ var res, req, reporter, matched, end, route, afterMatchContext, end1, cost, _afterMatchContext_router, current, url, status, matched1, middlewareContext, end2, cost1, renderResult, responseStream, response, afterRenderContext, end3, cost2;
661
673
  return _ts_generator(this, function(_state) {
662
674
  switch (_state.label) {
663
675
  case 0:
664
- res = context.res;
676
+ res = context.res, req = context.req, reporter = context.reporter;
665
677
  matched = _this.router.match(context.path);
666
678
  if (!matched) {
667
679
  _this.render404(context);
@@ -669,43 +681,65 @@ export var ModernServer = /* @__PURE__ */ function() {
669
681
  2
670
682
  ];
671
683
  }
684
+ return [
685
+ 4,
686
+ reporter.init({
687
+ match: matched
688
+ })
689
+ ];
690
+ case 1:
691
+ _state.sent();
692
+ end = time();
693
+ res.on("finish", function() {
694
+ var cost3 = end();
695
+ reporter.reportTiming("server_handle_request", cost3);
696
+ });
672
697
  route = matched.generate(context.url);
673
698
  if (!route.isApi)
674
699
  return [
675
700
  3,
676
- 2
701
+ 3
677
702
  ];
678
703
  return [
679
704
  4,
680
705
  _this.handleAPI(context)
681
706
  ];
682
- case 1:
707
+ case 2:
683
708
  _state.sent();
684
709
  return [
685
710
  2
686
711
  ];
687
- case 2:
712
+ case 3:
713
+ return [
714
+ 4,
715
+ bodyParser(req)
716
+ ];
717
+ case 4:
718
+ _state.sent();
688
719
  if (!route.entryName)
689
720
  return [
690
721
  3,
691
- 5
722
+ 7
692
723
  ];
693
724
  afterMatchContext = createAfterMatchContext(context, route.entryName);
694
725
  if (!(_this.runMode === RUN_MODE.FULL))
695
726
  return [
696
727
  3,
697
- 4
728
+ 6
698
729
  ];
730
+ end1 = time();
699
731
  return [
700
732
  4,
701
733
  _this.runner.afterMatch(afterMatchContext, {
702
734
  onLast: noop
703
735
  })
704
736
  ];
705
- case 3:
737
+ case 5:
706
738
  _state.sent();
707
- _state.label = 4;
708
- case 4:
739
+ cost = end1();
740
+ reporter.reportTiming("server_hook_after_render", cost);
741
+ _state.label = 6;
742
+ case 6:
709
743
  if (_this.isSend(res)) {
710
744
  return [
711
745
  2
@@ -728,34 +762,37 @@ export var ModernServer = /* @__PURE__ */ function() {
728
762
  }
729
763
  route = matched1.generate(context.url);
730
764
  }
731
- _state.label = 5;
732
- case 5:
765
+ _state.label = 7;
766
+ case 7:
733
767
  if (!_this.frameWebHandler)
734
768
  return [
735
769
  3,
736
- 7
770
+ 9
737
771
  ];
738
772
  res.locals = res.locals || {};
739
773
  middlewareContext = createMiddlewareContext(context);
774
+ end2 = time();
740
775
  return [
741
776
  4,
742
777
  _this.frameWebHandler(middlewareContext)
743
778
  ];
744
- case 6:
779
+ case 8:
745
780
  _state.sent();
781
+ cost1 = end2();
782
+ reporter.reportTiming("server_middleware", cost1);
746
783
  res.locals = _object_spread({}, res.locals, middlewareContext.response.locals);
747
784
  if (_this.isSend(res)) {
748
785
  return [
749
786
  2
750
787
  ];
751
788
  }
752
- _state.label = 7;
753
- case 7:
789
+ _state.label = 9;
790
+ case 9:
754
791
  return [
755
792
  4,
756
793
  _this.handleWeb(context, route)
757
794
  ];
758
- case 8:
795
+ case 10:
759
796
  renderResult = _state.sent();
760
797
  if (!renderResult) {
761
798
  return [
@@ -773,32 +810,35 @@ export var ModernServer = /* @__PURE__ */ function() {
773
810
  if (!route.entryName)
774
811
  return [
775
812
  3,
776
- 11
813
+ 13
777
814
  ];
778
815
  afterRenderContext = createAfterRenderContext(context, response.toString());
779
816
  if (!(_this.runMode === RUN_MODE.FULL))
780
817
  return [
781
818
  3,
782
- 10
819
+ 12
783
820
  ];
821
+ end3 = time();
784
822
  return [
785
823
  4,
786
824
  _this.runner.afterRender(afterRenderContext, {
787
825
  onLast: noop
788
826
  })
789
827
  ];
790
- case 9:
828
+ case 11:
791
829
  _state.sent();
792
- _state.label = 10;
793
- case 10:
830
+ cost2 = end3();
831
+ reporter.reportTiming("server_hook_after_render", cost2);
832
+ _state.label = 12;
833
+ case 12:
794
834
  if (_this.isSend(res)) {
795
835
  return [
796
836
  2
797
837
  ];
798
838
  }
799
839
  response = afterRenderContext.template.get();
800
- _state.label = 11;
801
- case 11:
840
+ _state.label = 13;
841
+ case 13:
802
842
  res.end(response);
803
843
  return [
804
844
  2
@@ -7,9 +7,9 @@ import { _ as _inherits } from "@swc/helpers/_/_inherits";
7
7
  import { _ as _create_super } from "@swc/helpers/_/_create_super";
8
8
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
9
9
  import { ModernServer } from "./modernServer";
10
- var ModernSSRServer = /* @__PURE__ */ function(ModernServer2) {
10
+ var ModernSSRServer = /* @__PURE__ */ function(ModernServer1) {
11
11
  "use strict";
12
- _inherits(ModernSSRServer2, ModernServer2);
12
+ _inherits(ModernSSRServer2, ModernServer1);
13
13
  var _super = _create_super(ModernSSRServer2);
14
14
  function ModernSSRServer2() {
15
15
  _class_call_check(this, ModernSSRServer2);
@@ -39,9 +39,9 @@ var ModernSSRServer = /* @__PURE__ */ function(ModernServer2) {
39
39
  ]);
40
40
  return ModernSSRServer2;
41
41
  }(ModernServer);
42
- var ModernAPIServer = /* @__PURE__ */ function(ModernServer2) {
42
+ var ModernAPIServer = /* @__PURE__ */ function(ModernServer1) {
43
43
  "use strict";
44
- _inherits(ModernAPIServer2, ModernServer2);
44
+ _inherits(ModernAPIServer2, ModernServer1);
45
45
  var _super = _create_super(ModernAPIServer2);
46
46
  function ModernAPIServer2() {
47
47
  _class_call_check(this, ModernAPIServer2);
@@ -65,9 +65,9 @@ var ModernAPIServer = /* @__PURE__ */ function(ModernServer2) {
65
65
  ]);
66
66
  return ModernAPIServer2;
67
67
  }(ModernServer);
68
- var ModernWebServer = /* @__PURE__ */ function(ModernServer2) {
68
+ var ModernWebServer = /* @__PURE__ */ function(ModernServer1) {
69
69
  "use strict";
70
- _inherits(ModernWebServer2, ModernServer2);
70
+ _inherits(ModernWebServer2, ModernServer1);
71
71
  var _super = _create_super(ModernWebServer2);
72
72
  function ModernWebServer2() {
73
73
  _class_call_check(this, ModernWebServer2);
package/dist/esm/utils.js CHANGED
@@ -1,5 +1,7 @@
1
+ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
1
2
  import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
3
  import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
4
+ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
3
5
  import { createDebugger } from "@modern-js/utils";
4
6
  export var debug = createDebugger("prod-server");
5
7
  export var mergeExtension = function(users) {
@@ -90,3 +92,58 @@ export var isRedirect = function(code) {
90
92
  308
91
93
  ].includes(code);
92
94
  };
95
+ function parseBodyTypes(headers, body) {
96
+ switch (headers["content-type"]) {
97
+ case "application/json":
98
+ return JSON.parse(body);
99
+ default:
100
+ return body;
101
+ }
102
+ }
103
+ var getRequestBody = function(req) {
104
+ return new Promise(function(resolve, reject) {
105
+ var _req;
106
+ if (((_req = req) === null || _req === void 0 ? void 0 : _req.method) && req.method.toLowerCase() !== "get") {
107
+ var body = "";
108
+ req.on("data", function(chunk) {
109
+ body += chunk.toString();
110
+ });
111
+ req.on("end", function() {
112
+ resolve(parseBodyTypes(req.headers, body));
113
+ });
114
+ req.on("error", function(err) {
115
+ reject(err);
116
+ });
117
+ } else {
118
+ resolve(void 0);
119
+ }
120
+ });
121
+ };
122
+ export var bodyParser = function() {
123
+ var _ref = _async_to_generator(function(req) {
124
+ return _ts_generator(this, function(_state) {
125
+ switch (_state.label) {
126
+ case 0:
127
+ if (!!req.body)
128
+ return [
129
+ 3,
130
+ 2
131
+ ];
132
+ return [
133
+ 4,
134
+ getRequestBody(req)
135
+ ];
136
+ case 1:
137
+ req.body = _state.sent();
138
+ _state.label = 2;
139
+ case 2:
140
+ return [
141
+ 2
142
+ ];
143
+ }
144
+ });
145
+ });
146
+ return function bodyParser2(req) {
147
+ return _ref.apply(this, arguments);
148
+ };
149
+ }();
@@ -9,6 +9,7 @@ import { createAfterMatchContext, createAfterRenderContext, createMiddlewareCont
9
9
  import { Logger } from "./libs/logger";
10
10
  import { RouteMatchManager } from "./libs/route";
11
11
  import { metrics as defaultMetrics } from "./libs/metrics";
12
+ import { defaultReporter } from "./libs/reporter";
12
13
  export var ReturnResponse = /* @__PURE__ */ function() {
13
14
  "use strict";
14
15
  function ReturnResponse2(body, status) {
@@ -91,7 +92,7 @@ export var createHandler = function(manifest) {
91
92
  routeMgr.reset(routes);
92
93
  return function() {
93
94
  var _ref = _async_to_generator(function(options) {
94
- var _page_serverHooks, _page_serverHooks_afterMatch, request, loadableStats, routeManifest, url, pageMatch, entryName, page, logger, metrics, hookContext, afterMatchHookContext, _page_serverHooks1, _page_serverHooks2, _page_serverHooks_afterRender, middlewarsHookContext, responseLike, params, baseUrl, serverRenderContext, body, afterRenderHookContext, e;
95
+ var _page_serverHooks_afterMatch, _page_serverHooks, _page, request, loadableStats, routeManifest, url, pageMatch, entryName, page, logger, metrics, reporter, hookContext, afterMatchHookContext, _page_serverHooks1, _page_serverHooks_afterRender, _page_serverHooks2, middlewarsHookContext, responseLike, params, baseUrl, serverRenderContext, body, afterRenderHookContext, e;
95
96
  function createServerRequest(url2, baseUrl2, request2, params2) {
96
97
  var pathname = url2.pathname, host = url2.host, searchParams = url2.searchParams;
97
98
  var rawHeaders = request2.headers;
@@ -128,9 +129,10 @@ export var createHandler = function(manifest) {
128
129
  level: "warn"
129
130
  });
130
131
  metrics = defaultMetrics;
131
- hookContext = createWorkerHookContext(request.url, logger, metrics);
132
+ reporter = defaultReporter;
133
+ hookContext = createWorkerHookContext(request.url, logger, metrics, reporter);
132
134
  afterMatchHookContext = createAfterMatchContext(hookContext, entryName);
133
- page === null || page === void 0 ? void 0 : (_page_serverHooks = page.serverHooks) === null || _page_serverHooks === void 0 ? void 0 : (_page_serverHooks_afterMatch = _page_serverHooks.afterMatch) === null || _page_serverHooks_afterMatch === void 0 ? void 0 : _page_serverHooks_afterMatch.call(_page_serverHooks, afterMatchHookContext, function() {
135
+ (_page = page) === null || _page === void 0 ? void 0 : (_page_serverHooks = _page.serverHooks) === null || _page_serverHooks === void 0 ? void 0 : (_page_serverHooks_afterMatch = _page_serverHooks.afterMatch) === null || _page_serverHooks_afterMatch === void 0 ? void 0 : _page_serverHooks_afterMatch.call(_page_serverHooks, afterMatchHookContext, function() {
134
136
  return void 0;
135
137
  });
136
138
  if (checkIsSent(hookContext)) {
@@ -182,9 +184,15 @@ export var createHandler = function(manifest) {
182
184
  template: page.template,
183
185
  entryName: page.entryName,
184
186
  logger: logger,
187
+ reporter: defaultReporter,
185
188
  metrics: metrics,
186
189
  // FIXME: pass correctly req & res
187
190
  req: request,
191
+ serverTiming: {
192
+ addServeTiming: function addServeTiming() {
193
+ return this;
194
+ }
195
+ },
188
196
  res: responseLike
189
197
  };
190
198
  return [
@@ -236,7 +244,7 @@ function createResponse(template) {
236
244
  return RESPONSE_NOTFOUND;
237
245
  }
238
246
  }
239
- function createWorkerHookContext(url, logger, metrics) {
247
+ function createWorkerHookContext(url, logger, metrics, reporter) {
240
248
  var _ref = [
241
249
  {
242
250
  headers: new Headers(),
@@ -250,7 +258,8 @@ function createWorkerHookContext(url, logger, metrics) {
250
258
  res: res,
251
259
  req: req,
252
260
  logger: logger,
253
- metrics: metrics
261
+ metrics: metrics,
262
+ reporter: reporter
254
263
  };
255
264
  }
256
265
  function applyMiddlewares(ctx, middleware) {
@@ -4,6 +4,7 @@ export { ModernServer } from "./server/modernServer";
4
4
  export { createProxyHandler } from "./libs/proxy";
5
5
  export * from "./type";
6
6
  export * from "./constants";
7
+ export { createRenderHandler } from "./libs/render";
7
8
  export default (options) => {
8
9
  if (options == null) {
9
10
  throw new Error("can not start mserver without options");
@@ -4,6 +4,9 @@ import qs from "querystring";
4
4
  import { Buffer } from "buffer";
5
5
  import createEtag from "etag";
6
6
  import fresh from "fresh";
7
+ import { cutNameByHyphen } from "@modern-js/utils";
8
+ import { ServerTiming } from "../serverTiming";
9
+ import { defaultReporter } from "../reporter";
7
10
  import { headersWithoutCookie } from "../../utils";
8
11
  const MOCK_URL_BASE = "https://modernjs.dev/";
9
12
  export class ModernServerContext {
@@ -149,15 +152,18 @@ export class ModernServerContext {
149
152
  this.logger.error(`Web Server Error - ${dig}, error = %s, req.url = %s, req.headers = %o`, e instanceof Error ? e.stack || e.message : e, this.path, headersWithoutCookie(this.headers));
150
153
  }
151
154
  constructor(req, res, options) {
155
+ var _options;
152
156
  _define_property(this, "req", void 0);
153
157
  _define_property(this, "res", void 0);
154
158
  _define_property(this, "params", {});
155
- _define_property(this, "serverData", void 0);
159
+ _define_property(this, "reporter", defaultReporter);
160
+ _define_property(this, "serverTiming", void 0);
161
+ _define_property(this, "serverData", {});
156
162
  _define_property(this, "options", {});
157
163
  this.req = req;
158
164
  this.res = res;
159
165
  this.options = options || {};
160
- this.serverData = {};
166
+ this.serverTiming = new ServerTiming(res, cutNameByHyphen(((_options = options) === null || _options === void 0 ? void 0 : _options.metaName) || "modern-js"));
161
167
  this.bind();
162
168
  }
163
169
  }
@@ -2,10 +2,11 @@ import { RouteAPI } from "./route";
2
2
  import { TemplateAPI } from "./template";
3
3
  import { BaseRequest, BaseResponse } from "./base";
4
4
  export const base = (context) => {
5
- const { res } = context;
5
+ const { res, reporter } = context;
6
6
  return {
7
7
  response: new BaseResponse(res),
8
8
  request: new BaseRequest(context),
9
+ reporter,
9
10
  logger: context.logger,
10
11
  metrics: context.metrics
11
12
  };
@@ -31,7 +31,7 @@ class ServerResponse {
31
31
  }
32
32
  }
33
33
  export const base = (context) => {
34
- const { req, res, logger, metrics } = context;
34
+ const { req, res, logger, metrics, reporter } = context;
35
35
  const serverResponse = new ServerResponse(res);
36
36
  const { host, pathname, searchParams } = new URL(req.url);
37
37
  const headers = {};
@@ -40,6 +40,7 @@ export const base = (context) => {
40
40
  });
41
41
  return {
42
42
  response: new BaseResponse(serverResponse),
43
+ reporter,
43
44
  request: new BaseRequest({
44
45
  url: req.url,
45
46
  host,
@@ -15,6 +15,7 @@ const createCacheConfig = (config = {}) => ({
15
15
  jest.setTimeout(6e4);
16
16
  describe("cache", () => {
17
17
  it("should cache correctly", async () => {
18
+ var _cacheResult;
18
19
  destroyCache();
19
20
  const cache = createCache();
20
21
  const context = {
@@ -28,7 +29,7 @@ describe("cache", () => {
28
29
  await cache.set(context, content, cacheConfig, true);
29
30
  const cacheResult = await cache.get(context);
30
31
  expect(cacheResult).not.toBe(null);
31
- expect(cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.content).toBe("hello");
32
+ expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe("hello");
32
33
  });
33
34
  it("should ignore cache set when cache config not exist", async () => {
34
35
  destroyCache();
@@ -123,6 +124,7 @@ describe("cache", () => {
123
124
  destroyCache();
124
125
  const cache = createCache();
125
126
  for (const cacheable of cacheabelAry) {
127
+ var _cacheResult;
126
128
  const context = {
127
129
  entry: "",
128
130
  pathname: cacheable.requestOpt.url,
@@ -132,13 +134,14 @@ describe("cache", () => {
132
134
  const cacheConfig = createCacheConfig(cacheable.cacheConfig || {});
133
135
  await cache.set(context, cacheable.content, cacheConfig, true);
134
136
  const cacheResult = await cache.get(context);
135
- expect(cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.content).toBe(cacheable.content);
137
+ expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe(cacheable.content);
136
138
  }
137
139
  });
138
140
  it("should match cache correctly", async () => {
139
141
  destroyCache();
140
142
  const cache = createCache();
141
143
  for (const cacheable of matchedCacheableAry) {
144
+ var _cacheResult;
142
145
  const [baseCacheable, matchOne, ...other] = cacheable;
143
146
  const { requestOpt = {}, cacheConfig, content } = baseCacheable;
144
147
  const context = {
@@ -155,7 +158,7 @@ describe("cache", () => {
155
158
  headers: matchOne.headers
156
159
  };
157
160
  const cacheResult = await cache.get(matchContext);
158
- expect(cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.content).toBe(content);
161
+ expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe(content);
159
162
  for (const notMatch of other) {
160
163
  const notMatchContext = {
161
164
  entry: "",
@@ -169,6 +172,7 @@ describe("cache", () => {
169
172
  }
170
173
  });
171
174
  it("should stale cache correctly", async () => {
175
+ var _freshResult, _staleResult;
172
176
  destroyCache();
173
177
  const cache = createCache();
174
178
  const context = {
@@ -184,16 +188,17 @@ describe("cache", () => {
184
188
  const shouldCache = await cache.set(context, content, config, true);
185
189
  expect(shouldCache.value).toBe(true);
186
190
  const freshResult = await cache.get(context);
187
- expect(freshResult === null || freshResult === void 0 ? void 0 : freshResult.isStale).toBe(false);
191
+ expect((_freshResult = freshResult) === null || _freshResult === void 0 ? void 0 : _freshResult.isStale).toBe(false);
188
192
  await new Promise((resolve) => {
189
193
  setTimeout(() => {
190
194
  resolve();
191
195
  }, 6e3);
192
196
  });
193
197
  const staleResult = await cache.get(context);
194
- expect(staleResult === null || staleResult === void 0 ? void 0 : staleResult.isStale).toBe(true);
198
+ expect((_staleResult = staleResult) === null || _staleResult === void 0 ? void 0 : _staleResult.isStale).toBe(true);
195
199
  });
196
200
  it("should garbage cache correctly", async () => {
201
+ var _freshResult, _staleResult;
197
202
  destroyCache();
198
203
  const cache = createCache();
199
204
  const context = {
@@ -210,13 +215,13 @@ describe("cache", () => {
210
215
  const shouldCache = await cache.set(context, content, config, true);
211
216
  expect(shouldCache.value).toBe(true);
212
217
  const freshResult = await cache.get(context);
213
- expect(freshResult === null || freshResult === void 0 ? void 0 : freshResult.isGarbage).toBe(false);
218
+ expect((_freshResult = freshResult) === null || _freshResult === void 0 ? void 0 : _freshResult.isGarbage).toBe(false);
214
219
  await new Promise((resolve) => {
215
220
  setTimeout(() => {
216
221
  resolve();
217
222
  }, 1e4);
218
223
  });
219
224
  const staleResult = await cache.get(context);
220
- expect(staleResult === null || staleResult === void 0 ? void 0 : staleResult.isGarbage).toBe(true);
225
+ expect((_staleResult = staleResult) === null || _staleResult === void 0 ? void 0 : _staleResult.isGarbage).toBe(true);
221
226
  });
222
227
  });
@@ -5,6 +5,7 @@ import { namespaceHash, withCoalescedInvoke } from "./util";
5
5
  export default (renderFn, ctx) => {
6
6
  const sprCache = createCache();
7
7
  const doRender = async (context) => {
8
+ var _cacheFile;
8
9
  const cacheContext = {
9
10
  entry: context.entryName,
10
11
  ...context.request
@@ -40,7 +41,7 @@ export default (renderFn, ctx) => {
40
41
  const renderResult = await renderFn(context);
41
42
  return afterRender(renderResult, saveHtmlIntoCache);
42
43
  }
43
- const cacheHash = cacheFile === null || cacheFile === void 0 ? void 0 : cacheFile.hash;
44
+ const cacheHash = (_cacheFile = cacheFile) === null || _cacheFile === void 0 ? void 0 : _cacheFile.hash;
44
45
  if (cacheFile.isGarbage) {
45
46
  const renderResult = await renderFn(context);
46
47
  return afterRender(renderResult, saveHtmlIntoCache);