@modern-js/runtime 2.33.1 → 2.35.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 (40) hide show
  1. package/dist/cjs/router/runtime/index.js +4 -0
  2. package/dist/cjs/ssr/cli/index.js +4 -2
  3. package/dist/cjs/ssr/index.node.js +2 -0
  4. package/dist/cjs/ssr/prefetch.js +17 -15
  5. package/dist/cjs/ssr/serverRender/renderToStream/buildTemplate.after.js +4 -1
  6. package/dist/cjs/ssr/serverRender/renderToStream/index.js +11 -2
  7. package/dist/cjs/ssr/serverRender/renderToStream/renderToPipe.js +0 -7
  8. package/dist/cjs/ssr/serverRender/renderToStream/renderToPipe.worker.js +3 -4
  9. package/dist/cjs/ssr/serverRender/renderToString/entry.js +2 -2
  10. package/dist/cjs/ssr/serverRender/tracker.js +14 -0
  11. package/dist/cjs/ssr/utils.js +4 -1
  12. package/dist/esm/router/runtime/index.js +1 -0
  13. package/dist/esm/ssr/cli/index.js +4 -2
  14. package/dist/esm/ssr/index.node.js +2 -0
  15. package/dist/esm/ssr/prefetch.js +18 -16
  16. package/dist/esm/ssr/serverRender/renderToStream/buildTemplate.after.js +4 -1
  17. package/dist/esm/ssr/serverRender/renderToStream/index.js +12 -3
  18. package/dist/esm/ssr/serverRender/renderToStream/renderToPipe.js +0 -7
  19. package/dist/esm/ssr/serverRender/renderToStream/renderToPipe.worker.js +3 -4
  20. package/dist/esm/ssr/serverRender/renderToString/entry.js +3 -3
  21. package/dist/esm/ssr/serverRender/tracker.js +11 -0
  22. package/dist/esm/ssr/utils.js +1 -1
  23. package/dist/esm-node/router/runtime/index.js +1 -0
  24. package/dist/esm-node/ssr/cli/index.js +4 -2
  25. package/dist/esm-node/ssr/index.node.js +2 -0
  26. package/dist/esm-node/ssr/prefetch.js +17 -15
  27. package/dist/esm-node/ssr/serverRender/renderToStream/buildTemplate.after.js +4 -1
  28. package/dist/esm-node/ssr/serverRender/renderToStream/index.js +11 -2
  29. package/dist/esm-node/ssr/serverRender/renderToStream/renderToPipe.js +0 -7
  30. package/dist/esm-node/ssr/serverRender/renderToStream/renderToPipe.worker.js +3 -4
  31. package/dist/esm-node/ssr/serverRender/renderToString/entry.js +3 -3
  32. package/dist/esm-node/ssr/serverRender/tracker.js +14 -0
  33. package/dist/esm-node/ssr/utils.js +4 -1
  34. package/dist/types/router/runtime/index.d.ts +1 -0
  35. package/dist/types/ssr/prefetch.d.ts +2 -1
  36. package/dist/types/ssr/serverRender/renderToString/entry.d.ts +2 -2
  37. package/dist/types/ssr/serverRender/renderToString/type.d.ts +0 -10
  38. package/dist/types/ssr/serverRender/tracker.d.ts +5 -2
  39. package/dist/types/ssr/serverRender/types.d.ts +13 -1
  40. package/package.json +11 -11
@@ -10,6 +10,9 @@ function _export(target, all) {
10
10
  });
11
11
  }
12
12
  _export(exports, {
13
+ renderRoutes: function() {
14
+ return _utils.renderRoutes;
15
+ },
13
16
  default: function() {
14
17
  return _default;
15
18
  },
@@ -202,6 +205,7 @@ _export(exports, {
202
205
  const _export_star = require("@swc/helpers/_/_export_star");
203
206
  const _router = require("@modern-js/utils/runtime/router");
204
207
  const _plugin = require("./plugin");
208
+ const _utils = require("./utils");
205
209
  _export_star._(require("./withRouter"), exports);
206
210
  const _PrefetchLink = require("./PrefetchLink");
207
211
  const _default = _plugin.routerPlugin;
@@ -142,17 +142,19 @@ const ssrPlugin = () => ({
142
142
  },
143
143
  modifyEntryRuntimePlugins({ entrypoint, plugins, bundlerConfigs }) {
144
144
  if (ssrConfigMap.get(entrypoint.entryName)) {
145
- var _bundlerConfigs_find_output, _bundlerConfigs_find, _bundlerConfigs;
145
+ var _bundlerConfigs_find_output, _bundlerConfigs_find, _bundlerConfigs, _config_server;
146
146
  const chunkLoadingGlobal = (_bundlerConfigs = bundlerConfigs) === null || _bundlerConfigs === void 0 ? void 0 : (_bundlerConfigs_find = _bundlerConfigs.find((config2) => config2.name === "client")) === null || _bundlerConfigs_find === void 0 ? void 0 : (_bundlerConfigs_find_output = _bundlerConfigs_find.output) === null || _bundlerConfigs_find_output === void 0 ? void 0 : _bundlerConfigs_find_output.chunkLoadingGlobal;
147
147
  const config = api.useResolvedConfigContext();
148
148
  const { crossorigin, scriptLoading } = config.html;
149
+ const disablePrerender = typeof ((_config_server = config.server) === null || _config_server === void 0 ? void 0 : _config_server.ssr) === "object" ? Boolean(config.server.ssr.disablePrerender) : false;
149
150
  plugins.push({
150
151
  name: PLUGIN_IDENTIFIER,
151
152
  options: JSON.stringify({
152
153
  ...ssrConfigMap.get(entrypoint.entryName) || {},
153
154
  crossorigin,
154
155
  scriptLoading,
155
- chunkLoadingGlobal
156
+ chunkLoadingGlobal,
157
+ disablePrerender
156
158
  })
157
159
  });
158
160
  }
@@ -21,6 +21,7 @@ const _export_star = require("@swc/helpers/_/_export_star");
21
21
  const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
22
22
  const _utils = require("./utils");
23
23
  const _serverRender = /* @__PURE__ */ _interop_require_default._(require("./serverRender"));
24
+ const _tracker = require("./serverRender/tracker");
24
25
  _export_star._(require("./react"), exports);
25
26
  const ssr = (config = {}) => ({
26
27
  name: "@modern-js/plugin-ssr",
@@ -38,6 +39,7 @@ const ssr = (config = {}) => ({
38
39
  const { request } = context.ssrContext;
39
40
  context.ssrContext.request = (0, _utils.formatServer)(request);
40
41
  context.ssrContext.mode = config.mode;
42
+ context.ssrContext.tracker = (0, _tracker.createSSRTracker)(context.ssrContext);
41
43
  if (!context.ssrContext.htmlModifiers) {
42
44
  context.ssrContext.htmlModifiers = [];
43
45
  }
@@ -12,24 +12,26 @@ const _jsxruntime = require("react/jsx-runtime");
12
12
  const _server = require("react-dom/server");
13
13
  const _runtimenode = require("@modern-js/utils/runtime-node");
14
14
  const _server1 = require("@loadable/server");
15
- const prefetch = async (App, context) => (0, _runtimenode.run)(context.ssrContext.request.headers, async () => {
15
+ const prefetch = async (App, context, config) => (0, _runtimenode.run)(context.ssrContext.request.headers, async () => {
16
16
  var _context_store, _context;
17
17
  const { ssrContext } = context;
18
18
  const { loadableStats } = ssrContext;
19
- if (loadableStats) {
20
- const extractor = new _server1.ChunkExtractor({
21
- stats: loadableStats,
22
- entrypoints: [
23
- ssrContext.entryName
24
- ].filter(Boolean)
25
- });
26
- (0, _server.renderToStaticMarkup)(extractor.collectChunks(/* @__PURE__ */ (0, _jsxruntime.jsx)(App, {
27
- context
28
- })));
29
- } else {
30
- (0, _server.renderToStaticMarkup)(/* @__PURE__ */ (0, _jsxruntime.jsx)(App, {
31
- context
32
- }));
19
+ if (!config.disablePrerender) {
20
+ if (loadableStats) {
21
+ const extractor = new _server1.ChunkExtractor({
22
+ stats: loadableStats,
23
+ entrypoints: [
24
+ ssrContext.entryName
25
+ ].filter(Boolean)
26
+ });
27
+ (0, _server.renderToStaticMarkup)(extractor.collectChunks(/* @__PURE__ */ (0, _jsxruntime.jsx)(App, {
28
+ context
29
+ })));
30
+ } else {
31
+ (0, _server.renderToStaticMarkup)(/* @__PURE__ */ (0, _jsxruntime.jsx)(App, {
32
+ context
33
+ }));
34
+ }
33
35
  }
34
36
  if (!context.loaderManager.hasPendingLoaders()) {
35
37
  return {
@@ -21,7 +21,7 @@ function buildShellAfterTemplate(afterAppTemplate, options) {
21
21
  return template.replace("<!--<?- SSRDataScript ?>-->", ssrDataScript);
22
22
  function buildSSRDataScript() {
23
23
  const { context: { ssrContext, initialData, __i18nData__ }, renderLevel } = options;
24
- const { request, enableUnsafeCtx, nonce } = ssrContext;
24
+ const { request, enableUnsafeCtx, nonce, tracker } = ssrContext;
25
25
  const unsafeContext = {
26
26
  headers: request.headers
27
27
  };
@@ -31,6 +31,9 @@ function buildShellAfterTemplate(afterAppTemplate, options) {
31
31
  i18nData: __i18nData__
32
32
  },
33
33
  context: {
34
+ reporter: {
35
+ sessionId: tracker.sessionId
36
+ },
34
37
  request: {
35
38
  params: request.params,
36
39
  query: request.query,
@@ -13,6 +13,7 @@ const _react = require("react");
13
13
  const _runtimenode = require("@modern-js/utils/runtime-node");
14
14
  const _time = require("@modern-js/utils/universal/time");
15
15
  const _prerender = require("../../react/prerender");
16
+ const _tracker = require("../tracker");
16
17
  const _renderToPipe = /* @__PURE__ */ _interop_require_default._(require("./renderToPipe"));
17
18
  const render = ({ App, context }) => {
18
19
  const { ssrContext } = context;
@@ -26,17 +27,25 @@ const render = ({ App, context }) => {
26
27
  ssr: true
27
28
  })
28
29
  });
30
+ const { tracker } = ssrContext;
29
31
  const pipe = (0, _renderToPipe.default)(rootElement, context, {
30
32
  onShellReady() {
31
33
  const cacheConfig = _prerender.PreRender.config();
32
34
  if (cacheConfig) {
33
35
  ssrContext.cacheConfig = cacheConfig;
34
36
  }
37
+ const cost = end();
38
+ tracker.trackTiming(_tracker.SSRTimings.SSR_RENDER_SHELL, cost);
35
39
  },
36
40
  onAllReady() {
37
41
  const cost = end();
38
- ssrContext.logger.debug("App Render To HTML cost = %d ms", cost);
39
- ssrContext.metrics.emitTimer("app.render.html.cost", cost);
42
+ tracker.trackTiming(_tracker.SSRTimings.SSR_RENDER_TOTAL, cost);
43
+ },
44
+ onShellError(e) {
45
+ tracker.trackError(_tracker.SSRErrors.RENDER_SHELL, e);
46
+ },
47
+ onError(error) {
48
+ tracker.trackError(_tracker.SSRErrors.RENDER_STREAM, error);
40
49
  }
41
50
  });
42
51
  return pipe;
@@ -64,17 +64,10 @@ function renderToPipe(rootElement, context, options) {
64
64
  },
65
65
  onShellError(error) {
66
66
  var _options_onShellError, _options;
67
- ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
68
67
  const { shellAfter, shellBefore } = (0, _template.getTemplates)(context, _types.RenderLevel.CLIENT_RENDER);
69
68
  const fallbackHtml = `${shellBefore}${shellAfter}`;
70
69
  resolve(fallbackHtml);
71
70
  (_options = options) === null || _options === void 0 ? void 0 : (_options_onShellError = _options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(_options, error);
72
- },
73
- onError(error) {
74
- var _options_onError, _options;
75
- ssrContext.logger.error("An error occurs during streaming SSR", error);
76
- ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
77
- (_options = options) === null || _options === void 0 ? void 0 : (_options_onError = _options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(_options, error);
78
71
  }
79
72
  });
80
73
  });
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "default", {
10
10
  });
11
11
  const _types = require("../types");
12
12
  const _common = require("../../../common");
13
+ const _tracker = require("../tracker");
13
14
  const _template = require("./template");
14
15
  var ShellChunkStatus;
15
16
  (function(ShellChunkStatus2) {
@@ -33,9 +34,7 @@ function renderToPipe(rootElement, context, options) {
33
34
  ...options,
34
35
  nonce: (_ssrContext = ssrContext) === null || _ssrContext === void 0 ? void 0 : _ssrContext.nonce,
35
36
  onError(error) {
36
- var _ssrContext2, _ssrContext12, _options_onError, _options;
37
- (_ssrContext2 = ssrContext) === null || _ssrContext2 === void 0 ? void 0 : _ssrContext2.logger.error("An error occurs during streaming SSR", error);
38
- (_ssrContext12 = ssrContext) === null || _ssrContext12 === void 0 ? void 0 : _ssrContext12.metrics.emitCounter("app.render.streaming.error", 1);
37
+ var _options_onError, _options;
39
38
  (_options = options) === null || _options === void 0 ? void 0 : (_options_onError = _options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(_options, error);
40
39
  }
41
40
  });
@@ -68,7 +67,7 @@ function renderToPipe(rootElement, context, options) {
68
67
  return injectableStream;
69
68
  } catch (err) {
70
69
  var _ssrContext1;
71
- (_ssrContext1 = ssrContext) === null || _ssrContext1 === void 0 ? void 0 : _ssrContext1.metrics.emitCounter("app.render.streaming.shell.error", 1);
70
+ (_ssrContext1 = ssrContext) === null || _ssrContext1 === void 0 ? void 0 : _ssrContext1.tracker.trackError(_tracker.SSRErrors.RENDER_SHELL, err);
72
71
  const { shellAfter: shellAfter2, shellBefore: shellBefore2 } = (0, _template.getTemplates)(context, _types.RenderLevel.CLIENT_RENDER);
73
72
  const fallbackHtml = `${shellBefore2}${shellAfter2}`;
74
73
  return fallbackHtml;
@@ -85,7 +85,7 @@ class Entry {
85
85
  let prefetchData;
86
86
  const end = (0, _time.time)();
87
87
  try {
88
- prefetchData = await (0, _prefetch.default)(this.App, context);
88
+ prefetchData = await (0, _prefetch.default)(this.App, context, this.pluginConfig);
89
89
  this.result.renderLevel = _types.RenderLevel.SERVER_PREFETCH;
90
90
  const prefetchCost = end();
91
91
  this.tracker.trackTiming(_tracker.SSRTimings.SSR_PREFETCH, prefetchCost);
@@ -152,7 +152,7 @@ class Entry {
152
152
  this.entryName = entryName;
153
153
  this.App = options.App;
154
154
  this.pluginConfig = config;
155
- this.tracker = (0, _tracker.createSSRTracker)(ctx);
155
+ this.tracker = ctx.tracker;
156
156
  this.metrics = ctx.metrics;
157
157
  this.htmlModifiers = ctx.htmlModifiers;
158
158
  this.nonce = nonce;
@@ -25,11 +25,14 @@ var SSRTimings;
25
25
  SSRTimings2[SSRTimings2["SSR_RENDER_TOTAL"] = 0] = "SSR_RENDER_TOTAL";
26
26
  SSRTimings2[SSRTimings2["SSR_PREFETCH"] = 1] = "SSR_PREFETCH";
27
27
  SSRTimings2[SSRTimings2["SSR_RENDER_HTML"] = 2] = "SSR_RENDER_HTML";
28
+ SSRTimings2[SSRTimings2["SSR_RENDER_SHELL"] = 3] = "SSR_RENDER_SHELL";
28
29
  })(SSRTimings || (SSRTimings = {}));
29
30
  var SSRErrors;
30
31
  (function(SSRErrors2) {
31
32
  SSRErrors2[SSRErrors2["PREFETCH"] = 0] = "PREFETCH";
32
33
  SSRErrors2[SSRErrors2["RENDER_HTML"] = 1] = "RENDER_HTML";
34
+ SSRErrors2[SSRErrors2["RENDER_STREAM"] = 2] = "RENDER_STREAM";
35
+ SSRErrors2[SSRErrors2["RENDER_SHELL"] = 3] = "RENDER_SHELL";
33
36
  })(SSRErrors || (SSRErrors = {}));
34
37
  const errors = {
35
38
  [SSRErrors.PREFETCH]: {
@@ -41,6 +44,14 @@ const errors = {
41
44
  reporter: "SSR Error - App Render To HTML",
42
45
  logger: "App Render To HTML",
43
46
  metrics: "app.render.html.error"
47
+ },
48
+ [SSRErrors.RENDER_STREAM]: {
49
+ reporter: "SSR Error - App Render To Streaming",
50
+ logger: "An error occurs during streaming SSR",
51
+ metrics: "app.render.streaming.error"
52
+ },
53
+ [SSRErrors.RENDER_SHELL]: {
54
+ metrics: "app.render.streaming.shell.error"
44
55
  }
45
56
  };
46
57
  const timings = {
@@ -61,6 +72,9 @@ const timings = {
61
72
  serverTiming: "ssr-render-total",
62
73
  metrics: "app.render.cost",
63
74
  logger: "App Render Total cost = %d ms"
75
+ },
76
+ [SSRTimings.SSR_RENDER_SHELL]: {
77
+ reporter: "ssr-render-shell"
64
78
  }
65
79
  };
66
80
  function createSSRTracker({ reporter, serverTiming, metrics, logger }) {
@@ -54,7 +54,10 @@ const formatClient = (request) => {
54
54
  cookie: document.cookie || "",
55
55
  userAgent: ((_request_headers = request.headers) === null || _request_headers === void 0 ? void 0 : _request_headers["user-agent"]) || navigator.userAgent,
56
56
  referer: request.referer || document.referrer,
57
- query: request.query || getQuery(),
57
+ query: {
58
+ ...getQuery(),
59
+ ...request.query
60
+ },
58
61
  url: location.href
59
62
  };
60
63
  };
@@ -1,5 +1,6 @@
1
1
  import { useRouteLoaderData as useRouteData } from "@modern-js/utils/runtime/router";
2
2
  import { routerPlugin } from "./plugin";
3
+ export { renderRoutes } from "./utils";
3
4
  export default routerPlugin;
4
5
  export { modifyRoutes } from "./plugin";
5
6
  export * from "./withRouter";
@@ -148,18 +148,20 @@ export var ssrPlugin = function() {
148
148
  modifyEntryRuntimePlugins: function modifyEntryRuntimePlugins(param) {
149
149
  var entrypoint = param.entrypoint, plugins = param.plugins, bundlerConfigs = param.bundlerConfigs;
150
150
  if (ssrConfigMap.get(entrypoint.entryName)) {
151
- var _bundlerConfigs_find_output, _bundlerConfigs_find, _bundlerConfigs;
151
+ var _bundlerConfigs_find_output, _bundlerConfigs_find, _bundlerConfigs, _config_server;
152
152
  var chunkLoadingGlobal = (_bundlerConfigs = bundlerConfigs) === null || _bundlerConfigs === void 0 ? void 0 : (_bundlerConfigs_find = _bundlerConfigs.find(function(config2) {
153
153
  return config2.name === "client";
154
154
  })) === null || _bundlerConfigs_find === void 0 ? void 0 : (_bundlerConfigs_find_output = _bundlerConfigs_find.output) === null || _bundlerConfigs_find_output === void 0 ? void 0 : _bundlerConfigs_find_output.chunkLoadingGlobal;
155
155
  var config = api.useResolvedConfigContext();
156
156
  var _config_html = config.html, crossorigin = _config_html.crossorigin, scriptLoading = _config_html.scriptLoading;
157
+ var disablePrerender = typeof ((_config_server = config.server) === null || _config_server === void 0 ? void 0 : _config_server.ssr) === "object" ? Boolean(config.server.ssr.disablePrerender) : false;
157
158
  plugins.push({
158
159
  name: PLUGIN_IDENTIFIER,
159
160
  options: JSON.stringify(_object_spread_props(_object_spread({}, ssrConfigMap.get(entrypoint.entryName) || {}), {
160
161
  crossorigin: crossorigin,
161
162
  scriptLoading: scriptLoading,
162
- chunkLoadingGlobal: chunkLoadingGlobal
163
+ chunkLoadingGlobal: chunkLoadingGlobal,
164
+ disablePrerender: disablePrerender
163
165
  }))
164
166
  });
165
167
  }
@@ -4,6 +4,7 @@ import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
4
4
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
5
5
  import { formatServer } from "./utils";
6
6
  import render from "./serverRender";
7
+ import { createSSRTracker } from "./serverRender/tracker";
7
8
  export var ssr = function() {
8
9
  var config = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
9
10
  return {
@@ -43,6 +44,7 @@ export var ssr = function() {
43
44
  var request = context.ssrContext.request;
44
45
  context.ssrContext.request = formatServer(request);
45
46
  context.ssrContext.mode = config.mode;
47
+ context.ssrContext.tracker = createSSRTracker(context.ssrContext);
46
48
  if (!context.ssrContext.htmlModifiers) {
47
49
  context.ssrContext.htmlModifiers = [];
48
50
  }
@@ -5,7 +5,7 @@ import { renderToStaticMarkup } from "react-dom/server";
5
5
  import { run } from "@modern-js/utils/runtime-node";
6
6
  import { ChunkExtractor } from "@loadable/server";
7
7
  var prefetch = function() {
8
- var _ref = _async_to_generator(function(App, context) {
8
+ var _ref = _async_to_generator(function(App, context, config) {
9
9
  return _ts_generator(this, function(_state) {
10
10
  return [
11
11
  2,
@@ -16,20 +16,22 @@ var prefetch = function() {
16
16
  case 0:
17
17
  ssrContext = context.ssrContext;
18
18
  loadableStats = ssrContext.loadableStats;
19
- if (loadableStats) {
20
- extractor = new ChunkExtractor({
21
- stats: loadableStats,
22
- entrypoints: [
23
- ssrContext.entryName
24
- ].filter(Boolean)
25
- });
26
- renderToStaticMarkup(extractor.collectChunks(/* @__PURE__ */ _jsx(App, {
27
- context: context
28
- })));
29
- } else {
30
- renderToStaticMarkup(/* @__PURE__ */ _jsx(App, {
31
- context: context
32
- }));
19
+ if (!config.disablePrerender) {
20
+ if (loadableStats) {
21
+ extractor = new ChunkExtractor({
22
+ stats: loadableStats,
23
+ entrypoints: [
24
+ ssrContext.entryName
25
+ ].filter(Boolean)
26
+ });
27
+ renderToStaticMarkup(extractor.collectChunks(/* @__PURE__ */ _jsx(App, {
28
+ context: context
29
+ })));
30
+ } else {
31
+ renderToStaticMarkup(/* @__PURE__ */ _jsx(App, {
32
+ context: context
33
+ }));
34
+ }
33
35
  }
34
36
  if (!context.loaderManager.hasPendingLoaders()) {
35
37
  return [
@@ -70,7 +72,7 @@ var prefetch = function() {
70
72
  ];
71
73
  });
72
74
  });
73
- return function prefetch2(App, context) {
75
+ return function prefetch2(App, context, config) {
74
76
  return _ref.apply(this, arguments);
75
77
  };
76
78
  }();
@@ -8,7 +8,7 @@ export function buildShellAfterTemplate(afterAppTemplate, options) {
8
8
  return template.replace("<!--<?- SSRDataScript ?>-->", ssrDataScript);
9
9
  function buildSSRDataScript() {
10
10
  var _options_context = options.context, ssrContext = _options_context.ssrContext, initialData = _options_context.initialData, __i18nData__ = _options_context.__i18nData__, renderLevel = options.renderLevel;
11
- var request = ssrContext.request, enableUnsafeCtx = ssrContext.enableUnsafeCtx, nonce = ssrContext.nonce;
11
+ var request = ssrContext.request, enableUnsafeCtx = ssrContext.enableUnsafeCtx, nonce = ssrContext.nonce, tracker = ssrContext.tracker;
12
12
  var unsafeContext = {
13
13
  headers: request.headers
14
14
  };
@@ -18,6 +18,9 @@ export function buildShellAfterTemplate(afterAppTemplate, options) {
18
18
  i18nData: __i18nData__
19
19
  },
20
20
  context: {
21
+ reporter: {
22
+ sessionId: tracker.sessionId
23
+ },
21
24
  request: _object_spread({
22
25
  params: request.params,
23
26
  query: request.query,
@@ -4,6 +4,7 @@ import { createElement } from "react";
4
4
  import { run } from "@modern-js/utils/runtime-node";
5
5
  import { time } from "@modern-js/utils/universal/time";
6
6
  import { PreRender } from "../../react/prerender";
7
+ import { SSRErrors, SSRTimings } from "../tracker";
7
8
  import renderToPipe from "./renderToPipe";
8
9
  export var render = function(param) {
9
10
  var App = param.App, context = param.context;
@@ -12,7 +13,7 @@ export var render = function(param) {
12
13
  throw new Error('The "ssrContext" must not be undefined, but received undefined');
13
14
  }
14
15
  return run(ssrContext.request.headers, /* @__PURE__ */ _async_to_generator(function() {
15
- var end, rootElement, pipe;
16
+ var end, rootElement, tracker, pipe;
16
17
  return _ts_generator(this, function(_state) {
17
18
  end = time();
18
19
  rootElement = createElement(App, {
@@ -20,17 +21,25 @@ export var render = function(param) {
20
21
  ssr: true
21
22
  })
22
23
  });
24
+ tracker = ssrContext.tracker;
23
25
  pipe = renderToPipe(rootElement, context, {
24
26
  onShellReady: function onShellReady() {
25
27
  var cacheConfig = PreRender.config();
26
28
  if (cacheConfig) {
27
29
  ssrContext.cacheConfig = cacheConfig;
28
30
  }
31
+ var cost = end();
32
+ tracker.trackTiming(SSRTimings.SSR_RENDER_SHELL, cost);
29
33
  },
30
34
  onAllReady: function onAllReady() {
31
35
  var cost = end();
32
- ssrContext.logger.debug("App Render To HTML cost = %d ms", cost);
33
- ssrContext.metrics.emitTimer("app.render.html.cost", cost);
36
+ tracker.trackTiming(SSRTimings.SSR_RENDER_TOTAL, cost);
37
+ },
38
+ onShellError: function onShellError(e) {
39
+ tracker.trackError(SSRErrors.RENDER_SHELL, e);
40
+ },
41
+ onError: function onError(error) {
42
+ tracker.trackError(SSRErrors.RENDER_STREAM, error);
34
43
  }
35
44
  });
36
45
  return [
@@ -56,17 +56,10 @@ function renderToPipe(rootElement, context, options) {
56
56
  },
57
57
  onShellError: function onShellError(error) {
58
58
  var _options_onShellError, _options;
59
- ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
60
59
  var _getTemplates = getTemplates(context, RenderLevel.CLIENT_RENDER), shellAfter = _getTemplates.shellAfter, shellBefore = _getTemplates.shellBefore;
61
60
  var fallbackHtml = "".concat(shellBefore).concat(shellAfter);
62
61
  resolve(fallbackHtml);
63
62
  (_options = options) === null || _options === void 0 ? void 0 : (_options_onShellError = _options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(_options, error);
64
- },
65
- onError: function onError(error) {
66
- var _options_onError, _options;
67
- ssrContext.logger.error("An error occurs during streaming SSR", error);
68
- ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
69
- (_options = options) === null || _options === void 0 ? void 0 : (_options_onError = _options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(_options, error);
70
63
  }
71
64
  })).pipe;
72
65
  });
@@ -4,6 +4,7 @@ import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
4
4
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
5
5
  import { RenderLevel } from "../types";
6
6
  import { ESCAPED_SHELL_STREAM_END_MARK } from "../../../common";
7
+ import { SSRErrors } from "../tracker";
7
8
  import { getTemplates } from "./template";
8
9
  var ShellChunkStatus;
9
10
  (function(ShellChunkStatus2) {
@@ -38,9 +39,7 @@ function renderToPipe(rootElement, context, options) {
38
39
  renderToReadableStream(rootElement, _object_spread_props(_object_spread({}, options), {
39
40
  nonce: (_ssrContext = ssrContext) === null || _ssrContext === void 0 ? void 0 : _ssrContext.nonce,
40
41
  onError: function onError(error) {
41
- var _ssrContext2, _ssrContext12, _options_onError, _options;
42
- (_ssrContext2 = ssrContext) === null || _ssrContext2 === void 0 ? void 0 : _ssrContext2.logger.error("An error occurs during streaming SSR", error);
43
- (_ssrContext12 = ssrContext) === null || _ssrContext12 === void 0 ? void 0 : _ssrContext12.metrics.emitCounter("app.render.streaming.error", 1);
42
+ var _options_onError, _options;
44
43
  (_options = options) === null || _options === void 0 ? void 0 : (_options_onError = _options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(_options, error);
45
44
  }
46
45
  }))
@@ -101,7 +100,7 @@ function renderToPipe(rootElement, context, options) {
101
100
  ];
102
101
  case 3:
103
102
  err = _state.sent();
104
- (_ssrContext1 = ssrContext) === null || _ssrContext1 === void 0 ? void 0 : _ssrContext1.metrics.emitCounter("app.render.streaming.shell.error", 1);
103
+ (_ssrContext1 = ssrContext) === null || _ssrContext1 === void 0 ? void 0 : _ssrContext1.tracker.trackError(SSRErrors.RENDER_SHELL, err);
105
104
  _getTemplates1 = getTemplates(context, RenderLevel.CLIENT_RENDER), shellAfter1 = _getTemplates1.shellAfter, shellBefore1 = _getTemplates1.shellBefore;
106
105
  fallbackHtml = "".concat(shellBefore1).concat(shellAfter1);
107
106
  return [
@@ -14,7 +14,7 @@ import helmetReplace from "../helmet";
14
14
  import { RenderLevel } from "../types";
15
15
  import prefetch from "../../prefetch";
16
16
  import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID, attributesToString } from "../utils";
17
- import { SSRErrors, SSRTimings, createSSRTracker } from "../tracker";
17
+ import { SSRErrors, SSRTimings } from "../tracker";
18
18
  import { createLoadableCollector } from "./loadable";
19
19
  import { createRender } from "./render";
20
20
  import { createStyledCollector } from "./styledComponent";
@@ -60,7 +60,7 @@ var Entry = /* @__PURE__ */ function() {
60
60
  this.entryName = entryName;
61
61
  this.App = options.App;
62
62
  this.pluginConfig = config;
63
- this.tracker = createSSRTracker(ctx);
63
+ this.tracker = ctx.tracker;
64
64
  this.metrics = ctx.metrics;
65
65
  this.htmlModifiers = ctx.htmlModifiers;
66
66
  this.nonce = nonce;
@@ -154,7 +154,7 @@ var Entry = /* @__PURE__ */ function() {
154
154
  ]);
155
155
  return [
156
156
  4,
157
- prefetch(_this.App, context)
157
+ prefetch(_this.App, context, _this.pluginConfig)
158
158
  ];
159
159
  case 2:
160
160
  prefetchData = _state.sent();
@@ -4,11 +4,14 @@ export var SSRTimings;
4
4
  SSRTimings2[SSRTimings2["SSR_RENDER_TOTAL"] = 0] = "SSR_RENDER_TOTAL";
5
5
  SSRTimings2[SSRTimings2["SSR_PREFETCH"] = 1] = "SSR_PREFETCH";
6
6
  SSRTimings2[SSRTimings2["SSR_RENDER_HTML"] = 2] = "SSR_RENDER_HTML";
7
+ SSRTimings2[SSRTimings2["SSR_RENDER_SHELL"] = 3] = "SSR_RENDER_SHELL";
7
8
  })(SSRTimings || (SSRTimings = {}));
8
9
  export var SSRErrors;
9
10
  (function(SSRErrors2) {
10
11
  SSRErrors2[SSRErrors2["PREFETCH"] = 0] = "PREFETCH";
11
12
  SSRErrors2[SSRErrors2["RENDER_HTML"] = 1] = "RENDER_HTML";
13
+ SSRErrors2[SSRErrors2["RENDER_STREAM"] = 2] = "RENDER_STREAM";
14
+ SSRErrors2[SSRErrors2["RENDER_SHELL"] = 3] = "RENDER_SHELL";
12
15
  })(SSRErrors || (SSRErrors = {}));
13
16
  var _obj;
14
17
  var errors = (_obj = {}, _define_property(_obj, SSRErrors.PREFETCH, {
@@ -19,6 +22,12 @@ var errors = (_obj = {}, _define_property(_obj, SSRErrors.PREFETCH, {
19
22
  reporter: "SSR Error - App Render To HTML",
20
23
  logger: "App Render To HTML",
21
24
  metrics: "app.render.html.error"
25
+ }), _define_property(_obj, SSRErrors.RENDER_STREAM, {
26
+ reporter: "SSR Error - App Render To Streaming",
27
+ logger: "An error occurs during streaming SSR",
28
+ metrics: "app.render.streaming.error"
29
+ }), _define_property(_obj, SSRErrors.RENDER_SHELL, {
30
+ metrics: "app.render.streaming.shell.error"
22
31
  }), _obj);
23
32
  var _obj1;
24
33
  var timings = (_obj1 = {}, _define_property(_obj1, SSRTimings.SSR_PREFETCH, {
@@ -36,6 +45,8 @@ var timings = (_obj1 = {}, _define_property(_obj1, SSRTimings.SSR_PREFETCH, {
36
45
  serverTiming: "ssr-render-total",
37
46
  metrics: "app.render.cost",
38
47
  logger: "App Render Total cost = %d ms"
48
+ }), _define_property(_obj1, SSRTimings.SSR_RENDER_SHELL, {
49
+ reporter: "ssr-render-shell"
39
50
  }), _obj1);
40
51
  export function createSSRTracker(param) {
41
52
  var reporter = param.reporter, serverTiming = param.serverTiming, metrics = param.metrics, logger = param.logger;
@@ -33,7 +33,7 @@ export var formatClient = function(request) {
33
33
  cookie: document.cookie || "",
34
34
  userAgent: ((_request_headers = request.headers) === null || _request_headers === void 0 ? void 0 : _request_headers["user-agent"]) || navigator.userAgent,
35
35
  referer: request.referer || document.referrer,
36
- query: request.query || getQuery(),
36
+ query: _object_spread({}, getQuery(), request.query),
37
37
  url: location.href
38
38
  };
39
39
  };
@@ -1,5 +1,6 @@
1
1
  import { useRouteLoaderData as useRouteData } from "@modern-js/utils/runtime/router";
2
2
  import { routerPlugin } from "./plugin";
3
+ export { renderRoutes } from "./utils";
3
4
  export default routerPlugin;
4
5
  export { modifyRoutes } from "./plugin";
5
6
  export * from "./withRouter";
@@ -122,17 +122,19 @@ export const ssrPlugin = () => ({
122
122
  },
123
123
  modifyEntryRuntimePlugins({ entrypoint, plugins, bundlerConfigs }) {
124
124
  if (ssrConfigMap.get(entrypoint.entryName)) {
125
- var _bundlerConfigs_find_output, _bundlerConfigs_find, _bundlerConfigs;
125
+ var _bundlerConfigs_find_output, _bundlerConfigs_find, _bundlerConfigs, _config_server;
126
126
  const chunkLoadingGlobal = (_bundlerConfigs = bundlerConfigs) === null || _bundlerConfigs === void 0 ? void 0 : (_bundlerConfigs_find = _bundlerConfigs.find((config2) => config2.name === "client")) === null || _bundlerConfigs_find === void 0 ? void 0 : (_bundlerConfigs_find_output = _bundlerConfigs_find.output) === null || _bundlerConfigs_find_output === void 0 ? void 0 : _bundlerConfigs_find_output.chunkLoadingGlobal;
127
127
  const config = api.useResolvedConfigContext();
128
128
  const { crossorigin, scriptLoading } = config.html;
129
+ const disablePrerender = typeof ((_config_server = config.server) === null || _config_server === void 0 ? void 0 : _config_server.ssr) === "object" ? Boolean(config.server.ssr.disablePrerender) : false;
129
130
  plugins.push({
130
131
  name: PLUGIN_IDENTIFIER,
131
132
  options: JSON.stringify({
132
133
  ...ssrConfigMap.get(entrypoint.entryName) || {},
133
134
  crossorigin,
134
135
  scriptLoading,
135
- chunkLoadingGlobal
136
+ chunkLoadingGlobal,
137
+ disablePrerender
136
138
  })
137
139
  });
138
140
  }
@@ -1,5 +1,6 @@
1
1
  import { formatServer } from "./utils";
2
2
  import render from "./serverRender";
3
+ import { createSSRTracker } from "./serverRender/tracker";
3
4
  export const ssr = (config = {}) => ({
4
5
  name: "@modern-js/plugin-ssr",
5
6
  setup: () => {
@@ -16,6 +17,7 @@ export const ssr = (config = {}) => ({
16
17
  const { request } = context.ssrContext;
17
18
  context.ssrContext.request = formatServer(request);
18
19
  context.ssrContext.mode = config.mode;
20
+ context.ssrContext.tracker = createSSRTracker(context.ssrContext);
19
21
  if (!context.ssrContext.htmlModifiers) {
20
22
  context.ssrContext.htmlModifiers = [];
21
23
  }
@@ -2,24 +2,26 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { renderToStaticMarkup } from "react-dom/server";
3
3
  import { run } from "@modern-js/utils/runtime-node";
4
4
  import { ChunkExtractor } from "@loadable/server";
5
- const prefetch = async (App, context) => run(context.ssrContext.request.headers, async () => {
5
+ const prefetch = async (App, context, config) => run(context.ssrContext.request.headers, async () => {
6
6
  var _context_store, _context;
7
7
  const { ssrContext } = context;
8
8
  const { loadableStats } = ssrContext;
9
- if (loadableStats) {
10
- const extractor = new ChunkExtractor({
11
- stats: loadableStats,
12
- entrypoints: [
13
- ssrContext.entryName
14
- ].filter(Boolean)
15
- });
16
- renderToStaticMarkup(extractor.collectChunks(/* @__PURE__ */ _jsx(App, {
17
- context
18
- })));
19
- } else {
20
- renderToStaticMarkup(/* @__PURE__ */ _jsx(App, {
21
- context
22
- }));
9
+ if (!config.disablePrerender) {
10
+ if (loadableStats) {
11
+ const extractor = new ChunkExtractor({
12
+ stats: loadableStats,
13
+ entrypoints: [
14
+ ssrContext.entryName
15
+ ].filter(Boolean)
16
+ });
17
+ renderToStaticMarkup(extractor.collectChunks(/* @__PURE__ */ _jsx(App, {
18
+ context
19
+ })));
20
+ } else {
21
+ renderToStaticMarkup(/* @__PURE__ */ _jsx(App, {
22
+ context
23
+ }));
24
+ }
23
25
  }
24
26
  if (!context.loaderManager.hasPendingLoaders()) {
25
27
  return {
@@ -11,7 +11,7 @@ export function buildShellAfterTemplate(afterAppTemplate, options) {
11
11
  return template.replace("<!--<?- SSRDataScript ?>-->", ssrDataScript);
12
12
  function buildSSRDataScript() {
13
13
  const { context: { ssrContext, initialData, __i18nData__ }, renderLevel } = options;
14
- const { request, enableUnsafeCtx, nonce } = ssrContext;
14
+ const { request, enableUnsafeCtx, nonce, tracker } = ssrContext;
15
15
  const unsafeContext = {
16
16
  headers: request.headers
17
17
  };
@@ -21,6 +21,9 @@ export function buildShellAfterTemplate(afterAppTemplate, options) {
21
21
  i18nData: __i18nData__
22
22
  },
23
23
  context: {
24
+ reporter: {
25
+ sessionId: tracker.sessionId
26
+ },
24
27
  request: {
25
28
  params: request.params,
26
29
  query: request.query,
@@ -2,6 +2,7 @@ import { createElement } from "react";
2
2
  import { run } from "@modern-js/utils/runtime-node";
3
3
  import { time } from "@modern-js/utils/universal/time";
4
4
  import { PreRender } from "../../react/prerender";
5
+ import { SSRErrors, SSRTimings } from "../tracker";
5
6
  import renderToPipe from "./renderToPipe";
6
7
  export const render = ({ App, context }) => {
7
8
  const { ssrContext } = context;
@@ -15,17 +16,25 @@ export const render = ({ App, context }) => {
15
16
  ssr: true
16
17
  })
17
18
  });
19
+ const { tracker } = ssrContext;
18
20
  const pipe = renderToPipe(rootElement, context, {
19
21
  onShellReady() {
20
22
  const cacheConfig = PreRender.config();
21
23
  if (cacheConfig) {
22
24
  ssrContext.cacheConfig = cacheConfig;
23
25
  }
26
+ const cost = end();
27
+ tracker.trackTiming(SSRTimings.SSR_RENDER_SHELL, cost);
24
28
  },
25
29
  onAllReady() {
26
30
  const cost = end();
27
- ssrContext.logger.debug("App Render To HTML cost = %d ms", cost);
28
- ssrContext.metrics.emitTimer("app.render.html.cost", cost);
31
+ tracker.trackTiming(SSRTimings.SSR_RENDER_TOTAL, cost);
32
+ },
33
+ onShellError(e) {
34
+ tracker.trackError(SSRErrors.RENDER_SHELL, e);
35
+ },
36
+ onError(error) {
37
+ tracker.trackError(SSRErrors.RENDER_STREAM, error);
29
38
  }
30
39
  });
31
40
  return pipe;
@@ -54,17 +54,10 @@ function renderToPipe(rootElement, context, options) {
54
54
  },
55
55
  onShellError(error) {
56
56
  var _options_onShellError, _options;
57
- ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
58
57
  const { shellAfter, shellBefore } = getTemplates(context, RenderLevel.CLIENT_RENDER);
59
58
  const fallbackHtml = `${shellBefore}${shellAfter}`;
60
59
  resolve(fallbackHtml);
61
60
  (_options = options) === null || _options === void 0 ? void 0 : (_options_onShellError = _options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(_options, error);
62
- },
63
- onError(error) {
64
- var _options_onError, _options;
65
- ssrContext.logger.error("An error occurs during streaming SSR", error);
66
- ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
67
- (_options = options) === null || _options === void 0 ? void 0 : (_options_onError = _options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(_options, error);
68
61
  }
69
62
  });
70
63
  });
@@ -1,5 +1,6 @@
1
1
  import { RenderLevel } from "../types";
2
2
  import { ESCAPED_SHELL_STREAM_END_MARK } from "../../../common";
3
+ import { SSRErrors } from "../tracker";
3
4
  import { getTemplates } from "./template";
4
5
  var ShellChunkStatus;
5
6
  (function(ShellChunkStatus2) {
@@ -23,9 +24,7 @@ function renderToPipe(rootElement, context, options) {
23
24
  ...options,
24
25
  nonce: (_ssrContext = ssrContext) === null || _ssrContext === void 0 ? void 0 : _ssrContext.nonce,
25
26
  onError(error) {
26
- var _ssrContext2, _ssrContext12, _options_onError, _options;
27
- (_ssrContext2 = ssrContext) === null || _ssrContext2 === void 0 ? void 0 : _ssrContext2.logger.error("An error occurs during streaming SSR", error);
28
- (_ssrContext12 = ssrContext) === null || _ssrContext12 === void 0 ? void 0 : _ssrContext12.metrics.emitCounter("app.render.streaming.error", 1);
27
+ var _options_onError, _options;
29
28
  (_options = options) === null || _options === void 0 ? void 0 : (_options_onError = _options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(_options, error);
30
29
  }
31
30
  });
@@ -58,7 +57,7 @@ function renderToPipe(rootElement, context, options) {
58
57
  return injectableStream;
59
58
  } catch (err) {
60
59
  var _ssrContext1;
61
- (_ssrContext1 = ssrContext) === null || _ssrContext1 === void 0 ? void 0 : _ssrContext1.metrics.emitCounter("app.render.streaming.shell.error", 1);
60
+ (_ssrContext1 = ssrContext) === null || _ssrContext1 === void 0 ? void 0 : _ssrContext1.tracker.trackError(SSRErrors.RENDER_SHELL, err);
62
61
  const { shellAfter: shellAfter2, shellBefore: shellBefore2 } = getTemplates(context, RenderLevel.CLIENT_RENDER);
63
62
  const fallbackHtml = `${shellBefore2}${shellAfter2}`;
64
63
  return fallbackHtml;
@@ -8,7 +8,7 @@ import helmetReplace from "../helmet";
8
8
  import { RenderLevel } from "../types";
9
9
  import prefetch from "../../prefetch";
10
10
  import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID, attributesToString } from "../utils";
11
- import { SSRErrors, SSRTimings, createSSRTracker } from "../tracker";
11
+ import { SSRErrors, SSRTimings } from "../tracker";
12
12
  import { createLoadableCollector } from "./loadable";
13
13
  import { createRender } from "./render";
14
14
  import { createStyledCollector } from "./styledComponent";
@@ -74,7 +74,7 @@ class Entry {
74
74
  let prefetchData;
75
75
  const end = time();
76
76
  try {
77
- prefetchData = await prefetch(this.App, context);
77
+ prefetchData = await prefetch(this.App, context, this.pluginConfig);
78
78
  this.result.renderLevel = RenderLevel.SERVER_PREFETCH;
79
79
  const prefetchCost = end();
80
80
  this.tracker.trackTiming(SSRTimings.SSR_PREFETCH, prefetchCost);
@@ -141,7 +141,7 @@ class Entry {
141
141
  this.entryName = entryName;
142
142
  this.App = options.App;
143
143
  this.pluginConfig = config;
144
- this.tracker = createSSRTracker(ctx);
144
+ this.tracker = ctx.tracker;
145
145
  this.metrics = ctx.metrics;
146
146
  this.htmlModifiers = ctx.htmlModifiers;
147
147
  this.nonce = nonce;
@@ -3,11 +3,14 @@ export var SSRTimings;
3
3
  SSRTimings2[SSRTimings2["SSR_RENDER_TOTAL"] = 0] = "SSR_RENDER_TOTAL";
4
4
  SSRTimings2[SSRTimings2["SSR_PREFETCH"] = 1] = "SSR_PREFETCH";
5
5
  SSRTimings2[SSRTimings2["SSR_RENDER_HTML"] = 2] = "SSR_RENDER_HTML";
6
+ SSRTimings2[SSRTimings2["SSR_RENDER_SHELL"] = 3] = "SSR_RENDER_SHELL";
6
7
  })(SSRTimings || (SSRTimings = {}));
7
8
  export var SSRErrors;
8
9
  (function(SSRErrors2) {
9
10
  SSRErrors2[SSRErrors2["PREFETCH"] = 0] = "PREFETCH";
10
11
  SSRErrors2[SSRErrors2["RENDER_HTML"] = 1] = "RENDER_HTML";
12
+ SSRErrors2[SSRErrors2["RENDER_STREAM"] = 2] = "RENDER_STREAM";
13
+ SSRErrors2[SSRErrors2["RENDER_SHELL"] = 3] = "RENDER_SHELL";
11
14
  })(SSRErrors || (SSRErrors = {}));
12
15
  const errors = {
13
16
  [SSRErrors.PREFETCH]: {
@@ -19,6 +22,14 @@ const errors = {
19
22
  reporter: "SSR Error - App Render To HTML",
20
23
  logger: "App Render To HTML",
21
24
  metrics: "app.render.html.error"
25
+ },
26
+ [SSRErrors.RENDER_STREAM]: {
27
+ reporter: "SSR Error - App Render To Streaming",
28
+ logger: "An error occurs during streaming SSR",
29
+ metrics: "app.render.streaming.error"
30
+ },
31
+ [SSRErrors.RENDER_SHELL]: {
32
+ metrics: "app.render.streaming.shell.error"
22
33
  }
23
34
  };
24
35
  const timings = {
@@ -39,6 +50,9 @@ const timings = {
39
50
  serverTiming: "ssr-render-total",
40
51
  metrics: "app.render.cost",
41
52
  logger: "App Render Total cost = %d ms"
53
+ },
54
+ [SSRTimings.SSR_RENDER_SHELL]: {
55
+ reporter: "ssr-render-shell"
42
56
  }
43
57
  };
44
58
  export function createSSRTracker({ reporter, serverTiming, metrics, logger }) {
@@ -28,7 +28,10 @@ export const formatClient = (request) => {
28
28
  cookie: document.cookie || "",
29
29
  userAgent: ((_request_headers = request.headers) === null || _request_headers === void 0 ? void 0 : _request_headers["user-agent"]) || navigator.userAgent,
30
30
  referer: request.referer || document.referrer,
31
- query: request.query || getQuery(),
31
+ query: {
32
+ ...getQuery(),
33
+ ...request.query
34
+ },
32
35
  url: location.href
33
36
  };
34
37
  };
@@ -2,6 +2,7 @@ import { useRouteLoaderData as useRouteData } from '@modern-js/utils/runtime/rou
2
2
  import { routerPlugin } from './plugin';
3
3
  import type { SingleRouteConfig, RouterConfig } from './types';
4
4
  export type { SingleRouteConfig, RouterConfig };
5
+ export { renderRoutes } from './utils';
5
6
  export default routerPlugin;
6
7
  export { modifyRoutes } from './plugin';
7
8
  export * from './withRouter';
@@ -1,5 +1,6 @@
1
1
  import { RuntimeContext } from '../core';
2
- declare const prefetch: (App: React.ComponentType<any>, context: RuntimeContext) => Promise<{
2
+ import { SSRPluginConfig } from './serverRender/types';
3
+ declare const prefetch: (App: React.ComponentType<any>, context: RuntimeContext, config: SSRPluginConfig) => Promise<{
3
4
  initialData: Record<string, unknown> | undefined;
4
5
  i18nData: any;
5
6
  loadersData?: undefined;
@@ -1,6 +1,6 @@
1
- import { RuntimeContext, ModernSSRReactComponent, SSRPluginConfig } from '../types';
1
+ import { RuntimeContext, ModernSSRReactComponent, SSRPluginConfig, SSRServerContext } from '../types';
2
2
  import { SSRTracker } from '../tracker';
3
- import { SSRServerContext, RenderResult } from './type';
3
+ import { RenderResult } from './type';
4
4
  type EntryOptions = {
5
5
  ctx: SSRServerContext;
6
6
  App: ModernSSRReactComponent;
@@ -1,18 +1,8 @@
1
- import type { BaseSSRServerContext } from '@modern-js/types';
2
- import type { BuildHtmlCb } from './buildHtml';
3
1
  export declare enum RenderLevel {
4
2
  CLIENT_RENDER = 0,
5
3
  SERVER_PREFETCH = 1,
6
4
  SERVER_RENDER = 2,
7
5
  }
8
- export type SSRServerContext = BaseSSRServerContext & {
9
- request: BaseSSRServerContext['request'] & {
10
- userAgent: string;
11
- cookie: string;
12
- cookieMap: Record<string, string>;
13
- };
14
- htmlModifiers: BuildHtmlCb[];
15
- };
16
6
  export type RenderResult = {
17
7
  renderLevel: RenderLevel;
18
8
  html?: string;
@@ -1,20 +1,23 @@
1
- import { SSRServerContext } from './types';
1
+ import type { BaseSSRServerContext } from '@modern-js/types';
2
2
  export type SSRTracker = ReturnType<typeof createSSRTracker>;
3
3
  export declare enum SSRTimings {
4
4
  SSR_RENDER_TOTAL = 0,
5
5
  SSR_PREFETCH = 1,
6
6
  SSR_RENDER_HTML = 2,
7
+ SSR_RENDER_SHELL = 3,
7
8
  }
8
9
  export declare enum SSRErrors {
9
10
  PREFETCH = 0,
10
11
  RENDER_HTML = 1,
12
+ RENDER_STREAM = 2,
13
+ RENDER_SHELL = 3,
11
14
  }
12
15
  export declare function createSSRTracker({
13
16
  reporter,
14
17
  serverTiming,
15
18
  metrics,
16
19
  logger
17
- }: SSRServerContext): {
20
+ }: BaseSSRServerContext): {
18
21
  readonly sessionId: string | undefined;
19
22
  trackError(key: SSRErrors, e: Error): void;
20
23
  trackTiming(key: SSRTimings, cost: number): void;
@@ -1,13 +1,25 @@
1
1
  /// <reference types="react" />
2
2
  import { ServerUserConfig } from '@modern-js/app-tools';
3
+ import type { BaseSSRServerContext } from '@modern-js/types';
3
4
  import type { RuntimeContext } from '../../core';
4
5
  import { RenderLevel } from './renderToString/type';
5
- export type { SSRServerContext } from './renderToString/type';
6
+ import type { BuildHtmlCb } from './renderToString/buildHtml';
7
+ import type { SSRTracker } from './tracker';
8
+ export type SSRServerContext = BaseSSRServerContext & {
9
+ request: BaseSSRServerContext['request'] & {
10
+ userAgent: string;
11
+ cookie: string;
12
+ cookieMap: Record<string, string>;
13
+ };
14
+ htmlModifiers: BuildHtmlCb[];
15
+ tracker: SSRTracker;
16
+ };
6
17
  export type ModernSSRReactComponent = React.ComponentType<any>;
7
18
  export { RuntimeContext, RenderLevel };
8
19
  export type SSRPluginConfig = {
9
20
  crossorigin?: boolean | 'anonymous' | 'use-credentials';
10
21
  scriptLoading?: 'defer' | 'blocking' | 'module';
22
+ disablePrerender?: boolean;
11
23
  chunkLoadingGlobal?: string;
12
24
  } & Exclude<ServerUserConfig['ssr'], boolean>;
13
25
  export type ServerRenderOptions = {
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.33.1",
18
+ "version": "2.35.0",
19
19
  "engines": {
20
20
  "node": ">=14.17.6"
21
21
  },
@@ -146,8 +146,8 @@
146
146
  }
147
147
  },
148
148
  "dependencies": {
149
- "@babel/core": "^7.21.8",
150
- "@babel/types": "^7.21.5",
149
+ "@babel/core": "^7.22.15",
150
+ "@babel/types": "^7.22.15",
151
151
  "cookie": "0.5.0",
152
152
  "@loadable/babel-plugin": "5.15.3",
153
153
  "@loadable/component": "5.15.3",
@@ -173,9 +173,9 @@
173
173
  "redux-logger": "^3.0.6",
174
174
  "styled-components": "^5.3.1",
175
175
  "@swc/helpers": "0.5.1",
176
- "@modern-js/plugin": "2.33.1",
177
- "@modern-js/types": "2.33.1",
178
- "@modern-js/utils": "2.33.1"
176
+ "@modern-js/plugin": "2.35.0",
177
+ "@modern-js/types": "2.35.0",
178
+ "@modern-js/utils": "2.35.0"
179
179
  },
180
180
  "peerDependencies": {
181
181
  "react": ">=17",
@@ -196,11 +196,11 @@
196
196
  "ts-jest": "^29.1.0",
197
197
  "typescript": "^5",
198
198
  "webpack": "^5.88.1",
199
- "@modern-js/app-tools": "2.33.1",
200
- "@scripts/build": "2.33.1",
201
- "@modern-js/server-core": "2.33.1",
202
- "@modern-js/core": "2.33.1",
203
- "@scripts/jest-config": "2.33.1"
199
+ "@modern-js/app-tools": "2.35.0",
200
+ "@modern-js/core": "2.35.0",
201
+ "@modern-js/server-core": "2.35.0",
202
+ "@scripts/build": "2.35.0",
203
+ "@scripts/jest-config": "2.35.0"
204
204
  },
205
205
  "sideEffects": false,
206
206
  "publishConfig": {