@modern-js/runtime 2.43.0 → 2.44.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 (33) hide show
  1. package/dist/cjs/ssr/serverRender/renderToStream/buildTemplate.share.js +1 -1
  2. package/dist/cjs/ssr/serverRender/renderToStream/bulidTemplate.before.js +36 -10
  3. package/dist/cjs/ssr/serverRender/renderToStream/index.js +2 -2
  4. package/dist/cjs/ssr/serverRender/renderToStream/renderToPipe.js +32 -30
  5. package/dist/cjs/ssr/serverRender/renderToStream/renderToPipe.worker.js +3 -3
  6. package/dist/cjs/ssr/serverRender/renderToStream/template.js +3 -3
  7. package/dist/cjs/ssr/serverRender/renderToString/loadable.js +2 -6
  8. package/dist/cjs/ssr/serverRender/utils.js +6 -0
  9. package/dist/esm/ssr/serverRender/renderToStream/buildTemplate.share.js +5 -3
  10. package/dist/esm/ssr/serverRender/renderToStream/bulidTemplate.before.js +168 -33
  11. package/dist/esm/ssr/serverRender/renderToStream/index.js +2 -2
  12. package/dist/esm/ssr/serverRender/renderToStream/renderToPipe.js +34 -30
  13. package/dist/esm/ssr/serverRender/renderToStream/renderToPipe.worker.js +23 -13
  14. package/dist/esm/ssr/serverRender/renderToStream/template.js +37 -11
  15. package/dist/esm/ssr/serverRender/renderToString/loadable.js +3 -7
  16. package/dist/esm/ssr/serverRender/utils.js +5 -0
  17. package/dist/esm-node/ssr/serverRender/renderToStream/buildTemplate.share.js +1 -1
  18. package/dist/esm-node/ssr/serverRender/renderToStream/bulidTemplate.before.js +37 -11
  19. package/dist/esm-node/ssr/serverRender/renderToStream/index.js +2 -2
  20. package/dist/esm-node/ssr/serverRender/renderToStream/renderToPipe.js +32 -30
  21. package/dist/esm-node/ssr/serverRender/renderToStream/renderToPipe.worker.js +3 -3
  22. package/dist/esm-node/ssr/serverRender/renderToStream/template.js +3 -3
  23. package/dist/esm-node/ssr/serverRender/renderToString/loadable.js +3 -7
  24. package/dist/esm-node/ssr/serverRender/utils.js +5 -0
  25. package/dist/types/ssr/serverRender/renderToStream/buildTemplate.after.d.ts +1 -1
  26. package/dist/types/ssr/serverRender/renderToStream/buildTemplate.share.d.ts +2 -2
  27. package/dist/types/ssr/serverRender/renderToStream/bulidTemplate.before.d.ts +2 -2
  28. package/dist/types/ssr/serverRender/renderToStream/index.d.ts +1 -1
  29. package/dist/types/ssr/serverRender/renderToStream/renderToPipe.d.ts +2 -2
  30. package/dist/types/ssr/serverRender/renderToStream/renderToPipe.worker.d.ts +2 -2
  31. package/dist/types/ssr/serverRender/renderToStream/template.d.ts +2 -2
  32. package/dist/types/ssr/serverRender/utils.d.ts +1 -0
  33. package/package.json +10 -10
@@ -24,7 +24,7 @@ __export(buildTemplate_share_exports, {
24
24
  module.exports = __toCommonJS(buildTemplate_share_exports);
25
25
  const HEAD_REG_EXP = /<head(.|\n)*>(.|\n)*<\/head>/;
26
26
  function buildTemplate(template, callbacks) {
27
- return callbacks.reduce((template2, buildTemplateCb) => buildTemplateCb(template2), template);
27
+ return callbacks.reduce((promise, buildTemplateCb) => promise.then((template2) => buildTemplateCb(template2)), Promise.resolve(template));
28
28
  }
29
29
  // Annotate the CommonJS export names for ESM import in node:
30
30
  0 && (module.exports = {
@@ -37,7 +37,24 @@ var import_helmet = __toESM(require("../helmet"));
37
37
  var import_constants = require("../constants");
38
38
  var import_utils = require("../utils");
39
39
  var import_buildTemplate = require("./buildTemplate.share");
40
- function getHeadTemplate(beforeEntryTemplate, context) {
40
+ const readAsset = async (chunk) => {
41
+ const fs = await Promise.resolve().then(() => __toESM(require("fs/promises")));
42
+ const path = await Promise.resolve().then(() => __toESM(require("path")));
43
+ const filepath = path.join(__dirname, chunk);
44
+ return fs.readFile(filepath, "utf-8");
45
+ };
46
+ const checkIsInline = (chunk, enableInline) => {
47
+ if (process.env.NODE_ENV === "production") {
48
+ if (enableInline instanceof RegExp) {
49
+ return enableInline.test(chunk);
50
+ } else {
51
+ return Boolean(enableInline);
52
+ }
53
+ } else {
54
+ return false;
55
+ }
56
+ };
57
+ function getHeadTemplate(beforeEntryTemplate, context, pluginConfig) {
41
58
  const callbacks = [
42
59
  (headTemplate2) => {
43
60
  const helmetData = import_react_helmet.default.renderStatic();
@@ -51,9 +68,10 @@ function getHeadTemplate(beforeEntryTemplate, context) {
51
68
  return "";
52
69
  }
53
70
  return (0, import_buildTemplate.buildTemplate)(headTemplate, callbacks);
54
- function injectCss(headTemplate2) {
55
- return (0, import_utils.safeReplace)(headTemplate2, import_constants.CHUNK_CSS_PLACEHOLDER, getCssChunks());
56
- function getCssChunks() {
71
+ async function injectCss(headTemplate2) {
72
+ const css = await getCssChunks();
73
+ return (0, import_utils.safeReplace)(headTemplate2, import_constants.CHUNK_CSS_PLACEHOLDER, css);
74
+ async function getCssChunks() {
57
75
  const { routeManifest, routerContext, routes } = context;
58
76
  if (!routeManifest || !routerContext || !routes) {
59
77
  return "";
@@ -75,15 +93,23 @@ function getHeadTemplate(beforeEntryTemplate, context) {
75
93
  }
76
94
  }
77
95
  });
78
- const styleLinks = cssChunks.map((chunk) => {
79
- return `<link href="${chunk}" rel="stylesheet" />`;
80
- });
81
- return `${styleLinks.join("")}`;
96
+ const { enableInlineStyles } = pluginConfig;
97
+ const styles = await Promise.all(cssChunks.map(async (chunk) => {
98
+ const link = `<link href="${chunk}" rel="stylesheet" />`;
99
+ if ((0, import_utils.checkIsNode)() && checkIsInline(chunk, enableInlineStyles)) {
100
+ return readAsset(chunk).then((content) => `<style>${content}</style>`).catch((_) => {
101
+ return link;
102
+ });
103
+ } else {
104
+ return link;
105
+ }
106
+ }));
107
+ return `${styles.join("")}`;
82
108
  }
83
109
  }
84
110
  }
85
- function buildShellBeforeTemplate(beforeAppTemplate, context) {
86
- const headTemplate = getHeadTemplate(beforeAppTemplate, context);
111
+ async function buildShellBeforeTemplate(beforeAppTemplate, context, pluginConfig) {
112
+ const headTemplate = await getHeadTemplate(beforeAppTemplate, context, pluginConfig);
87
113
  return beforeAppTemplate.replace(import_buildTemplate.HEAD_REG_EXP, headTemplate);
88
114
  }
89
115
  // Annotate the CommonJS export names for ESM import in node:
@@ -36,7 +36,7 @@ var import_node = require("@modern-js/runtime-utils/node");
36
36
  var import_time = require("@modern-js/runtime-utils/time");
37
37
  var import_tracker = require("../tracker");
38
38
  var import_renderToPipe = __toESM(require("./renderToPipe"));
39
- const render = ({ App, context }) => {
39
+ const render = ({ App, context, config }) => {
40
40
  const { ssrContext } = context;
41
41
  if (!ssrContext) {
42
42
  throw new Error('The "ssrContext" must not be undefined, but received undefined');
@@ -49,7 +49,7 @@ const render = ({ App, context }) => {
49
49
  })
50
50
  });
51
51
  const { tracker } = ssrContext;
52
- const pipe = (0, import_renderToPipe.default)(rootElement, context, {
52
+ const pipe = (0, import_renderToPipe.default)(rootElement, context, config, {
53
53
  onShellReady() {
54
54
  const cost = end();
55
55
  tracker.trackTiming(import_tracker.SSRTimings.RENDER_SHELL, cost);
@@ -30,7 +30,7 @@ var ShellChunkStatus;
30
30
  ShellChunkStatus2[ShellChunkStatus2["START"] = 0] = "START";
31
31
  ShellChunkStatus2[ShellChunkStatus2["FINIESH"] = 1] = "FINIESH";
32
32
  })(ShellChunkStatus || (ShellChunkStatus = {}));
33
- function renderToPipe(rootElement, context, options) {
33
+ function renderToPipe(rootElement, context, pluginConfig, options) {
34
34
  let shellChunkStatus = 0;
35
35
  const { ssrContext } = context;
36
36
  const chunkVec = [];
@@ -45,41 +45,43 @@ function renderToPipe(rootElement, context, options) {
45
45
  ...options,
46
46
  nonce: ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.nonce,
47
47
  onShellReady() {
48
- var _options_onShellReady;
49
- const { shellAfter, shellBefore } = (0, import_template.getTemplates)(context, import_types.RenderLevel.SERVER_RENDER);
50
- options === null || options === void 0 ? void 0 : (_options_onShellReady = options.onShellReady) === null || _options_onShellReady === void 0 ? void 0 : _options_onShellReady.call(options);
51
- const injectableTransform = new import_stream.Transform({
52
- transform(chunk, _encoding, callback) {
53
- try {
54
- if (shellChunkStatus !== 1) {
55
- chunkVec.push(chunk.toString());
56
- let concatedChunk = chunkVec.join("");
57
- if (concatedChunk.endsWith(import_common.ESCAPED_SHELL_STREAM_END_MARK)) {
58
- concatedChunk = concatedChunk.replace(import_common.ESCAPED_SHELL_STREAM_END_MARK, "");
59
- shellChunkStatus = 1;
60
- this.push(`${shellBefore}${concatedChunk}${shellAfter}`);
48
+ (0, import_template.getTemplates)(context, import_types.RenderLevel.SERVER_RENDER, pluginConfig).then(({ shellAfter, shellBefore }) => {
49
+ var _options_onShellReady;
50
+ options === null || options === void 0 ? void 0 : (_options_onShellReady = options.onShellReady) === null || _options_onShellReady === void 0 ? void 0 : _options_onShellReady.call(options);
51
+ const injectableTransform = new import_stream.Transform({
52
+ transform(chunk, _encoding, callback) {
53
+ try {
54
+ if (shellChunkStatus !== 1) {
55
+ chunkVec.push(chunk.toString());
56
+ let concatedChunk = chunkVec.join("");
57
+ if (concatedChunk.endsWith(import_common.ESCAPED_SHELL_STREAM_END_MARK)) {
58
+ concatedChunk = concatedChunk.replace(import_common.ESCAPED_SHELL_STREAM_END_MARK, "");
59
+ shellChunkStatus = 1;
60
+ this.push(`${shellBefore}${concatedChunk}${shellAfter}`);
61
+ }
62
+ } else {
63
+ this.push(chunk);
64
+ }
65
+ callback();
66
+ } catch (e) {
67
+ if (e instanceof Error) {
68
+ callback(e);
69
+ } else {
70
+ callback(new Error("Received unkown error when streaming"));
61
71
  }
62
- } else {
63
- this.push(chunk);
64
- }
65
- callback();
66
- } catch (e) {
67
- if (e instanceof Error) {
68
- callback(e);
69
- } else {
70
- callback(new Error("Received unkown error when streaming"));
71
72
  }
72
73
  }
73
- }
74
+ });
75
+ resolve(pipe(injectableTransform).pipe(stream));
74
76
  });
75
- resolve(pipe(injectableTransform).pipe(stream));
76
77
  },
77
78
  onShellError(error) {
78
- var _options_onShellError;
79
- const { shellAfter, shellBefore } = (0, import_template.getTemplates)(context, import_types.RenderLevel.CLIENT_RENDER);
80
- const fallbackHtml = `${shellBefore}${shellAfter}`;
81
- resolve(fallbackHtml);
82
- options === null || options === void 0 ? void 0 : (_options_onShellError = options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(options, error);
79
+ (0, import_template.getTemplates)(context, import_types.RenderLevel.CLIENT_RENDER, pluginConfig).then(({ shellAfter, shellBefore }) => {
80
+ var _options_onShellError;
81
+ const fallbackHtml = `${shellBefore}${shellAfter}`;
82
+ resolve(fallbackHtml);
83
+ options === null || options === void 0 ? void 0 : (_options_onShellError = options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(options, error);
84
+ });
83
85
  }
84
86
  });
85
87
  });
@@ -30,7 +30,7 @@ var ShellChunkStatus;
30
30
  ShellChunkStatus2[ShellChunkStatus2["START"] = 0] = "START";
31
31
  ShellChunkStatus2[ShellChunkStatus2["FINIESH"] = 1] = "FINIESH";
32
32
  })(ShellChunkStatus || (ShellChunkStatus = {}));
33
- function renderToPipe(rootElement, context, options) {
33
+ function renderToPipe(rootElement, context, pluginConfig, options) {
34
34
  let shellChunkStatus = 0;
35
35
  const chunkVec = [];
36
36
  const { ssrContext } = context;
@@ -40,7 +40,7 @@ function renderToPipe(rootElement, context, options) {
40
40
  ({ renderToReadableStream } = require("react-dom/server"));
41
41
  } catch (e) {
42
42
  }
43
- const { shellAfter, shellBefore } = (0, import_template.getTemplates)(context, import_types.RenderLevel.SERVER_RENDER);
43
+ const { shellAfter, shellBefore } = await (0, import_template.getTemplates)(context, import_types.RenderLevel.SERVER_RENDER, pluginConfig);
44
44
  try {
45
45
  const readableOriginal = await renderToReadableStream(rootElement, {
46
46
  ...options,
@@ -79,7 +79,7 @@ function renderToPipe(rootElement, context, options) {
79
79
  return injectableStream;
80
80
  } catch (err) {
81
81
  ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.tracker.trackError(import_tracker.SSRErrors.RENDER_SHELL, err);
82
- const { shellAfter: shellAfter2, shellBefore: shellBefore2 } = (0, import_template.getTemplates)(context, import_types.RenderLevel.CLIENT_RENDER);
82
+ const { shellAfter: shellAfter2, shellBefore: shellBefore2 } = await (0, import_template.getTemplates)(context, import_types.RenderLevel.CLIENT_RENDER, pluginConfig);
83
83
  const fallbackHtml = `${shellBefore2}${shellAfter2}`;
84
84
  return fallbackHtml;
85
85
  }
@@ -24,11 +24,11 @@ module.exports = __toCommonJS(template_exports);
24
24
  var import_buildTemplate = require("./buildTemplate.after");
25
25
  var import_bulidTemplate = require("./bulidTemplate.before");
26
26
  const HTML_SEPARATOR = "<!--<?- html ?>-->";
27
- const getTemplates = (context, renderLevel) => {
27
+ const getTemplates = async (context, renderLevel, pluginConfig) => {
28
28
  const { ssrContext } = context;
29
29
  const [beforeAppTemplate = "", afterAppHtmlTemplate = ""] = ssrContext.template.split(HTML_SEPARATOR) || [];
30
- const builtBeforeTemplate = (0, import_bulidTemplate.buildShellBeforeTemplate)(beforeAppTemplate, context);
31
- const builtAfterTemplate = (0, import_buildTemplate.buildShellAfterTemplate)(afterAppHtmlTemplate, {
30
+ const builtBeforeTemplate = await (0, import_bulidTemplate.buildShellBeforeTemplate)(beforeAppTemplate, context, pluginConfig);
31
+ const builtAfterTemplate = await (0, import_buildTemplate.buildShellAfterTemplate)(afterAppHtmlTemplate, {
32
32
  context,
33
33
  renderLevel
34
34
  });
@@ -58,10 +58,6 @@ const readAsset = async (chunk) => {
58
58
  const filepath = path.resolve(__dirname, chunk.filename);
59
59
  return fs.readFile(filepath, "utf-8");
60
60
  };
61
- const checkIsNode = () => {
62
- var _process_release;
63
- return typeof process !== "undefined" && ((_process_release = process.release) === null || _process_release === void 0 ? void 0 : _process_release.name) === "node";
64
- };
65
61
  class LoadableCollector {
66
62
  get existsAssets() {
67
63
  var _routeManifest_routeAssets_entryName, _routeManifest_routeAssets;
@@ -121,7 +117,7 @@ class LoadableCollector {
121
117
  return !jsChunkReg.test(template) && !((_this_existsAssets = this.existsAssets) === null || _this_existsAssets === void 0 ? void 0 : _this_existsAssets.includes(chunk.path));
122
118
  }).map(async (chunk) => {
123
119
  const script = `<script${attributes} src="${chunk.url}"></script>`;
124
- if (checkIsInline(chunk, enableInlineScripts) && checkIsNode()) {
120
+ if ((0, import_utils.checkIsNode)() && checkIsInline(chunk, enableInlineScripts)) {
125
121
  return readAsset(chunk).then((content) => `<script>${content}</script>`).catch((_) => {
126
122
  return script;
127
123
  });
@@ -140,7 +136,7 @@ class LoadableCollector {
140
136
  return !cssChunkReg.test(template) && !((_this_existsAssets = this.existsAssets) === null || _this_existsAssets === void 0 ? void 0 : _this_existsAssets.includes(chunk.path));
141
137
  }).map(async (chunk) => {
142
138
  const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
143
- if (checkIsInline(chunk, enableInlineStyles) && checkIsNode()) {
139
+ if ((0, import_utils.checkIsNode)() && checkIsInline(chunk, enableInlineStyles)) {
144
140
  return readAsset(chunk).then((content) => `<style>${content}</style>`).catch((_) => {
145
141
  return link;
146
142
  });
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var utils_exports = {};
20
20
  __export(utils_exports, {
21
21
  attributesToString: () => attributesToString,
22
+ checkIsNode: () => checkIsNode,
22
23
  safeReplace: () => safeReplace
23
24
  });
24
25
  module.exports = __toCommonJS(utils_exports);
@@ -30,8 +31,13 @@ function attributesToString(attributes) {
30
31
  function safeReplace(source, searchValue, replaceValue) {
31
32
  return source.replace(searchValue, () => replaceValue);
32
33
  }
34
+ function checkIsNode() {
35
+ var _process_release;
36
+ return typeof process !== "undefined" && ((_process_release = process.release) === null || _process_release === void 0 ? void 0 : _process_release.name) === "node";
37
+ }
33
38
  // Annotate the CommonJS export names for ESM import in node:
34
39
  0 && (module.exports = {
35
40
  attributesToString,
41
+ checkIsNode,
36
42
  safeReplace
37
43
  });
@@ -1,8 +1,10 @@
1
1
  var HEAD_REG_EXP = /<head(.|\n)*>(.|\n)*<\/head>/;
2
2
  function buildTemplate(template, callbacks) {
3
- return callbacks.reduce(function(template2, buildTemplateCb) {
4
- return buildTemplateCb(template2);
5
- }, template);
3
+ return callbacks.reduce(function(promise, buildTemplateCb) {
4
+ return promise.then(function(template2) {
5
+ return buildTemplateCb(template2);
6
+ });
7
+ }, Promise.resolve(template));
6
8
  }
7
9
  export {
8
10
  HEAD_REG_EXP,
@@ -1,12 +1,56 @@
1
+ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
+ import { _ as _instanceof } from "@swc/helpers/_/_instanceof";
1
3
  import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
2
4
  import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
5
+ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
3
6
  import ReactHelmet from "react-helmet";
4
7
  import { matchRoutes } from "@modern-js/runtime-utils/router";
5
8
  import helmetReplace from "../helmet";
6
9
  import { CHUNK_CSS_PLACEHOLDER } from "../constants";
7
- import { safeReplace } from "../utils";
10
+ import { checkIsNode, safeReplace } from "../utils";
8
11
  import { HEAD_REG_EXP, buildTemplate } from "./buildTemplate.share";
9
- function getHeadTemplate(beforeEntryTemplate, context) {
12
+ var readAsset = function() {
13
+ var _ref = _async_to_generator(function(chunk) {
14
+ var fs, path, filepath;
15
+ return _ts_generator(this, function(_state) {
16
+ switch (_state.label) {
17
+ case 0:
18
+ return [
19
+ 4,
20
+ import("fs/promises")
21
+ ];
22
+ case 1:
23
+ fs = _state.sent();
24
+ return [
25
+ 4,
26
+ import("path")
27
+ ];
28
+ case 2:
29
+ path = _state.sent();
30
+ filepath = path.join(__dirname, chunk);
31
+ return [
32
+ 2,
33
+ fs.readFile(filepath, "utf-8")
34
+ ];
35
+ }
36
+ });
37
+ });
38
+ return function readAsset2(chunk) {
39
+ return _ref.apply(this, arguments);
40
+ };
41
+ }();
42
+ var checkIsInline = function(chunk, enableInline) {
43
+ if (process.env.NODE_ENV === "production") {
44
+ if (_instanceof(enableInline, RegExp)) {
45
+ return enableInline.test(chunk);
46
+ } else {
47
+ return Boolean(enableInline);
48
+ }
49
+ } else {
50
+ return false;
51
+ }
52
+ };
53
+ function getHeadTemplate(beforeEntryTemplate, context, pluginConfig) {
10
54
  var callbacks = [
11
55
  function(headTemplate2) {
12
56
  var helmetData = ReactHelmet.renderStatic();
@@ -21,42 +65,133 @@ function getHeadTemplate(beforeEntryTemplate, context) {
21
65
  }
22
66
  return buildTemplate(headTemplate, callbacks);
23
67
  function injectCss(headTemplate2) {
24
- return safeReplace(headTemplate2, CHUNK_CSS_PLACEHOLDER, getCssChunks());
25
- function getCssChunks() {
26
- var routeManifest = context.routeManifest, routerContext = context.routerContext, routes = context.routes;
27
- if (!routeManifest || !routerContext || !routes) {
28
- return "";
68
+ return _injectCss.apply(this, arguments);
69
+ }
70
+ function _injectCss() {
71
+ _injectCss = _async_to_generator(function(headTemplate2) {
72
+ var css;
73
+ function getCssChunks() {
74
+ return _getCssChunks.apply(this, arguments);
29
75
  }
30
- var routeAssets = routeManifest.routeAssets;
31
- var cssChunks = [];
32
- var matches = matchRoutes(routes, routerContext.location, routerContext.basename);
33
- matches === null || matches === void 0 ? void 0 : matches.forEach(function(match, index) {
34
- if (!index) {
35
- return;
36
- }
37
- var routeId = match.route.id;
38
- if (routeId) {
39
- var routeManifest2 = routeAssets[routeId];
40
- if (routeManifest2) {
41
- var _cssChunks;
42
- var _routeManifest_referenceCssAssets = routeManifest2.referenceCssAssets, referenceCssAssets = _routeManifest_referenceCssAssets === void 0 ? [] : _routeManifest_referenceCssAssets;
43
- var _cssChunks1 = referenceCssAssets.filter(function(asset) {
44
- return (asset === null || asset === void 0 ? void 0 : asset.endsWith(".css")) && !headTemplate2.includes(asset);
45
- });
46
- (_cssChunks = cssChunks).push.apply(_cssChunks, _to_consumable_array(_cssChunks1));
47
- }
76
+ function _getCssChunks() {
77
+ _getCssChunks = _async_to_generator(function() {
78
+ var routeManifest, routerContext, routes, routeAssets, cssChunks, matches, enableInlineStyles, styles;
79
+ return _ts_generator(this, function(_state) {
80
+ switch (_state.label) {
81
+ case 0:
82
+ routeManifest = context.routeManifest, routerContext = context.routerContext, routes = context.routes;
83
+ if (!routeManifest || !routerContext || !routes) {
84
+ return [
85
+ 2,
86
+ ""
87
+ ];
88
+ }
89
+ routeAssets = routeManifest.routeAssets;
90
+ cssChunks = [];
91
+ matches = matchRoutes(routes, routerContext.location, routerContext.basename);
92
+ matches === null || matches === void 0 ? void 0 : matches.forEach(function(match, index) {
93
+ if (!index) {
94
+ return;
95
+ }
96
+ var routeId = match.route.id;
97
+ if (routeId) {
98
+ var routeManifest2 = routeAssets[routeId];
99
+ if (routeManifest2) {
100
+ var _cssChunks;
101
+ var _routeManifest_referenceCssAssets = routeManifest2.referenceCssAssets, referenceCssAssets = _routeManifest_referenceCssAssets === void 0 ? [] : _routeManifest_referenceCssAssets;
102
+ var _cssChunks1 = referenceCssAssets.filter(function(asset) {
103
+ return (asset === null || asset === void 0 ? void 0 : asset.endsWith(".css")) && !headTemplate2.includes(asset);
104
+ });
105
+ (_cssChunks = cssChunks).push.apply(_cssChunks, _to_consumable_array(_cssChunks1));
106
+ }
107
+ }
108
+ });
109
+ enableInlineStyles = pluginConfig.enableInlineStyles;
110
+ return [
111
+ 4,
112
+ Promise.all(cssChunks.map(function() {
113
+ var _ref2 = _async_to_generator(function(chunk) {
114
+ var link;
115
+ return _ts_generator(this, function(_state2) {
116
+ link = '<link href="'.concat(chunk, '" rel="stylesheet" />');
117
+ if (checkIsNode() && checkIsInline(chunk, enableInlineStyles)) {
118
+ return [
119
+ 2,
120
+ readAsset(chunk).then(function(content) {
121
+ return "<style>".concat(content, "</style>");
122
+ }).catch(function(_) {
123
+ return link;
124
+ })
125
+ ];
126
+ } else {
127
+ return [
128
+ 2,
129
+ link
130
+ ];
131
+ }
132
+ return [
133
+ 2
134
+ ];
135
+ });
136
+ });
137
+ return function(chunk) {
138
+ return _ref2.apply(this, arguments);
139
+ };
140
+ }()))
141
+ ];
142
+ case 1:
143
+ styles = _state.sent();
144
+ return [
145
+ 2,
146
+ "".concat(styles.join(""))
147
+ ];
148
+ }
149
+ });
150
+ });
151
+ return _getCssChunks.apply(this, arguments);
152
+ }
153
+ return _ts_generator(this, function(_state) {
154
+ switch (_state.label) {
155
+ case 0:
156
+ return [
157
+ 4,
158
+ getCssChunks()
159
+ ];
160
+ case 1:
161
+ css = _state.sent();
162
+ return [
163
+ 2,
164
+ safeReplace(headTemplate2, CHUNK_CSS_PLACEHOLDER, css)
165
+ ];
48
166
  }
49
167
  });
50
- var styleLinks = cssChunks.map(function(chunk) {
51
- return '<link href="'.concat(chunk, '" rel="stylesheet" />');
52
- });
53
- return "".concat(styleLinks.join(""));
54
- }
168
+ });
169
+ return _injectCss.apply(this, arguments);
55
170
  }
56
171
  }
57
- function buildShellBeforeTemplate(beforeAppTemplate, context) {
58
- var headTemplate = getHeadTemplate(beforeAppTemplate, context);
59
- return beforeAppTemplate.replace(HEAD_REG_EXP, headTemplate);
172
+ function buildShellBeforeTemplate(beforeAppTemplate, context, pluginConfig) {
173
+ return _buildShellBeforeTemplate.apply(this, arguments);
174
+ }
175
+ function _buildShellBeforeTemplate() {
176
+ _buildShellBeforeTemplate = _async_to_generator(function(beforeAppTemplate, context, pluginConfig) {
177
+ var headTemplate;
178
+ return _ts_generator(this, function(_state) {
179
+ switch (_state.label) {
180
+ case 0:
181
+ return [
182
+ 4,
183
+ getHeadTemplate(beforeAppTemplate, context, pluginConfig)
184
+ ];
185
+ case 1:
186
+ headTemplate = _state.sent();
187
+ return [
188
+ 2,
189
+ beforeAppTemplate.replace(HEAD_REG_EXP, headTemplate)
190
+ ];
191
+ }
192
+ });
193
+ });
194
+ return _buildShellBeforeTemplate.apply(this, arguments);
60
195
  }
61
196
  export {
62
197
  buildShellBeforeTemplate
@@ -6,7 +6,7 @@ import { time } from "@modern-js/runtime-utils/time";
6
6
  import { SSRErrors, SSRTimings } from "../tracker";
7
7
  import renderToPipe from "./renderToPipe";
8
8
  var render = function(param) {
9
- var App = param.App, context = param.context;
9
+ var App = param.App, context = param.context, config = param.config;
10
10
  var ssrContext = context.ssrContext;
11
11
  if (!ssrContext) {
12
12
  throw new Error('The "ssrContext" must not be undefined, but received undefined');
@@ -21,7 +21,7 @@ var render = function(param) {
21
21
  })
22
22
  });
23
23
  tracker = ssrContext.tracker;
24
- pipe = renderToPipe(rootElement, context, {
24
+ pipe = renderToPipe(rootElement, context, config, {
25
25
  onShellReady: function onShellReady() {
26
26
  var cost = end();
27
27
  tracker.trackTiming(SSRTimings.RENDER_SHELL, cost);
@@ -10,7 +10,7 @@ var ShellChunkStatus;
10
10
  ShellChunkStatus2[ShellChunkStatus2["START"] = 0] = "START";
11
11
  ShellChunkStatus2[ShellChunkStatus2["FINIESH"] = 1] = "FINIESH";
12
12
  })(ShellChunkStatus || (ShellChunkStatus = {}));
13
- function renderToPipe(rootElement, context, options) {
13
+ function renderToPipe(rootElement, context, pluginConfig, options) {
14
14
  var shellChunkStatus = 0;
15
15
  var ssrContext = context.ssrContext;
16
16
  var chunkVec = [];
@@ -24,41 +24,45 @@ function renderToPipe(rootElement, context, options) {
24
24
  var pipe = renderToPipeableStream(rootElement, _object_spread_props(_object_spread({}, options), {
25
25
  nonce: ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.nonce,
26
26
  onShellReady: function onShellReady() {
27
- var _options_onShellReady;
28
- var _getTemplates = getTemplates(context, RenderLevel.SERVER_RENDER), shellAfter = _getTemplates.shellAfter, shellBefore = _getTemplates.shellBefore;
29
- options === null || options === void 0 ? void 0 : (_options_onShellReady = options.onShellReady) === null || _options_onShellReady === void 0 ? void 0 : _options_onShellReady.call(options);
30
- var injectableTransform = new Transform({
31
- transform: function transform(chunk, _encoding, callback) {
32
- try {
33
- if (shellChunkStatus !== 1) {
34
- chunkVec.push(chunk.toString());
35
- var concatedChunk = chunkVec.join("");
36
- if (concatedChunk.endsWith(ESCAPED_SHELL_STREAM_END_MARK)) {
37
- concatedChunk = concatedChunk.replace(ESCAPED_SHELL_STREAM_END_MARK, "");
38
- shellChunkStatus = 1;
39
- this.push("".concat(shellBefore).concat(concatedChunk).concat(shellAfter));
27
+ getTemplates(context, RenderLevel.SERVER_RENDER, pluginConfig).then(function(param) {
28
+ var shellAfter = param.shellAfter, shellBefore = param.shellBefore;
29
+ var _options_onShellReady;
30
+ options === null || options === void 0 ? void 0 : (_options_onShellReady = options.onShellReady) === null || _options_onShellReady === void 0 ? void 0 : _options_onShellReady.call(options);
31
+ var injectableTransform = new Transform({
32
+ transform: function transform(chunk, _encoding, callback) {
33
+ try {
34
+ if (shellChunkStatus !== 1) {
35
+ chunkVec.push(chunk.toString());
36
+ var concatedChunk = chunkVec.join("");
37
+ if (concatedChunk.endsWith(ESCAPED_SHELL_STREAM_END_MARK)) {
38
+ concatedChunk = concatedChunk.replace(ESCAPED_SHELL_STREAM_END_MARK, "");
39
+ shellChunkStatus = 1;
40
+ this.push("".concat(shellBefore).concat(concatedChunk).concat(shellAfter));
41
+ }
42
+ } else {
43
+ this.push(chunk);
44
+ }
45
+ callback();
46
+ } catch (e) {
47
+ if (_instanceof(e, Error)) {
48
+ callback(e);
49
+ } else {
50
+ callback(new Error("Received unkown error when streaming"));
40
51
  }
41
- } else {
42
- this.push(chunk);
43
- }
44
- callback();
45
- } catch (e) {
46
- if (_instanceof(e, Error)) {
47
- callback(e);
48
- } else {
49
- callback(new Error("Received unkown error when streaming"));
50
52
  }
51
53
  }
52
- }
54
+ });
55
+ resolve(pipe(injectableTransform).pipe(stream));
53
56
  });
54
- resolve(pipe(injectableTransform).pipe(stream));
55
57
  },
56
58
  onShellError: function onShellError(error) {
57
- var _options_onShellError;
58
- var _getTemplates = getTemplates(context, RenderLevel.CLIENT_RENDER), shellAfter = _getTemplates.shellAfter, shellBefore = _getTemplates.shellBefore;
59
- var fallbackHtml = "".concat(shellBefore).concat(shellAfter);
60
- resolve(fallbackHtml);
61
- options === null || options === void 0 ? void 0 : (_options_onShellError = options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(options, error);
59
+ getTemplates(context, RenderLevel.CLIENT_RENDER, pluginConfig).then(function(param) {
60
+ var shellAfter = param.shellAfter, shellBefore = param.shellBefore;
61
+ var _options_onShellError;
62
+ var fallbackHtml = "".concat(shellBefore).concat(shellAfter);
63
+ resolve(fallbackHtml);
64
+ options === null || options === void 0 ? void 0 : (_options_onShellError = options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(options, error);
65
+ });
62
66
  }
63
67
  })).pipe;
64
68
  });
@@ -11,13 +11,13 @@ var ShellChunkStatus;
11
11
  ShellChunkStatus2[ShellChunkStatus2["START"] = 0] = "START";
12
12
  ShellChunkStatus2[ShellChunkStatus2["FINIESH"] = 1] = "FINIESH";
13
13
  })(ShellChunkStatus || (ShellChunkStatus = {}));
14
- function renderToPipe(rootElement, context, options) {
14
+ function renderToPipe(rootElement, context, pluginConfig, options) {
15
15
  var shellChunkStatus = 0;
16
16
  var chunkVec = [];
17
17
  var ssrContext = context.ssrContext;
18
18
  var forUserPipe = function() {
19
19
  var _ref = _async_to_generator(function() {
20
- var renderToReadableStream, _getTemplates, shellAfter, shellBefore, readableOriginal, reader, injectableStream, err, _getTemplates1, shellAfter1, shellBefore1, fallbackHtml;
20
+ var renderToReadableStream, _ref2, shellAfter, shellBefore, readableOriginal, reader, injectableStream, err, _ref1, shellAfter1, shellBefore1, fallbackHtml;
21
21
  return _ts_generator(this, function(_state) {
22
22
  switch (_state.label) {
23
23
  case 0:
@@ -25,14 +25,19 @@ function renderToPipe(rootElement, context, options) {
25
25
  renderToReadableStream = require("react-dom/server").renderToReadableStream;
26
26
  } catch (e) {
27
27
  }
28
- _getTemplates = getTemplates(context, RenderLevel.SERVER_RENDER), shellAfter = _getTemplates.shellAfter, shellBefore = _getTemplates.shellBefore;
29
- _state.label = 1;
28
+ return [
29
+ 4,
30
+ getTemplates(context, RenderLevel.SERVER_RENDER, pluginConfig)
31
+ ];
30
32
  case 1:
33
+ _ref2 = _state.sent(), shellAfter = _ref2.shellAfter, shellBefore = _ref2.shellBefore;
34
+ _state.label = 2;
35
+ case 2:
31
36
  _state.trys.push([
32
- 1,
33
- 3,
37
+ 2,
38
+ 4,
34
39
  ,
35
- 4
40
+ 6
36
41
  ]);
37
42
  return [
38
43
  4,
@@ -44,7 +49,7 @@ function renderToPipe(rootElement, context, options) {
44
49
  }
45
50
  }))
46
51
  ];
47
- case 2:
52
+ case 3:
48
53
  readableOriginal = _state.sent();
49
54
  reader = readableOriginal.getReader();
50
55
  injectableStream = new ReadableStream({
@@ -54,7 +59,7 @@ function renderToPipe(rootElement, context, options) {
54
59
  }
55
60
  function _push() {
56
61
  _push = _async_to_generator(function() {
57
- var _ref2, done, value, chunk, concatedChunk;
62
+ var _ref3, done, value, chunk, concatedChunk;
58
63
  return _ts_generator(this, function(_state2) {
59
64
  switch (_state2.label) {
60
65
  case 0:
@@ -63,7 +68,7 @@ function renderToPipe(rootElement, context, options) {
63
68
  reader.read()
64
69
  ];
65
70
  case 1:
66
- _ref2 = _state2.sent(), done = _ref2.done, value = _ref2.value;
71
+ _ref3 = _state2.sent(), done = _ref3.done, value = _ref3.value;
67
72
  if (done) {
68
73
  controller.close();
69
74
  return [
@@ -98,16 +103,21 @@ function renderToPipe(rootElement, context, options) {
98
103
  2,
99
104
  injectableStream
100
105
  ];
101
- case 3:
106
+ case 4:
102
107
  err = _state.sent();
103
108
  ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.tracker.trackError(SSRErrors.RENDER_SHELL, err);
104
- _getTemplates1 = getTemplates(context, RenderLevel.CLIENT_RENDER), shellAfter1 = _getTemplates1.shellAfter, shellBefore1 = _getTemplates1.shellBefore;
109
+ return [
110
+ 4,
111
+ getTemplates(context, RenderLevel.CLIENT_RENDER, pluginConfig)
112
+ ];
113
+ case 5:
114
+ _ref1 = _state.sent(), shellAfter1 = _ref1.shellAfter, shellBefore1 = _ref1.shellBefore;
105
115
  fallbackHtml = "".concat(shellBefore1).concat(shellAfter1);
106
116
  return [
107
117
  2,
108
118
  fallbackHtml
109
119
  ];
110
- case 4:
120
+ case 6:
111
121
  return [
112
122
  2
113
123
  ];
@@ -1,20 +1,46 @@
1
+ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
1
2
  import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
3
+ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
2
4
  import { buildShellAfterTemplate } from "./buildTemplate.after";
3
5
  import { buildShellBeforeTemplate } from "./bulidTemplate.before";
4
6
  var HTML_SEPARATOR = "<!--<?- html ?>-->";
5
- var getTemplates = function(context, renderLevel) {
6
- var ssrContext = context.ssrContext;
7
- var _ref = _sliced_to_array(ssrContext.template.split(HTML_SEPARATOR) || [], 2), tmp = _ref[0], beforeAppTemplate = tmp === void 0 ? "" : tmp, tmp1 = _ref[1], afterAppHtmlTemplate = tmp1 === void 0 ? "" : tmp1;
8
- var builtBeforeTemplate = buildShellBeforeTemplate(beforeAppTemplate, context);
9
- var builtAfterTemplate = buildShellAfterTemplate(afterAppHtmlTemplate, {
10
- context,
11
- renderLevel
7
+ var getTemplates = function() {
8
+ var _ref = _async_to_generator(function(context, renderLevel, pluginConfig) {
9
+ var ssrContext, _ref2, tmp, beforeAppTemplate, tmp1, afterAppHtmlTemplate, builtBeforeTemplate, builtAfterTemplate;
10
+ return _ts_generator(this, function(_state) {
11
+ switch (_state.label) {
12
+ case 0:
13
+ ssrContext = context.ssrContext;
14
+ _ref2 = _sliced_to_array(ssrContext.template.split(HTML_SEPARATOR) || [], 2), tmp = _ref2[0], beforeAppTemplate = tmp === void 0 ? "" : tmp, tmp1 = _ref2[1], afterAppHtmlTemplate = tmp1 === void 0 ? "" : tmp1;
15
+ return [
16
+ 4,
17
+ buildShellBeforeTemplate(beforeAppTemplate, context, pluginConfig)
18
+ ];
19
+ case 1:
20
+ builtBeforeTemplate = _state.sent();
21
+ return [
22
+ 4,
23
+ buildShellAfterTemplate(afterAppHtmlTemplate, {
24
+ context,
25
+ renderLevel
26
+ })
27
+ ];
28
+ case 2:
29
+ builtAfterTemplate = _state.sent();
30
+ return [
31
+ 2,
32
+ {
33
+ shellBefore: builtBeforeTemplate,
34
+ shellAfter: builtAfterTemplate
35
+ }
36
+ ];
37
+ }
38
+ });
12
39
  });
13
- return {
14
- shellBefore: builtBeforeTemplate,
15
- shellAfter: builtAfterTemplate
40
+ return function getTemplates2(context, renderLevel, pluginConfig) {
41
+ return _ref.apply(this, arguments);
16
42
  };
17
- };
43
+ }();
18
44
  export {
19
45
  getTemplates
20
46
  };
@@ -6,7 +6,7 @@ import { _ as _instanceof } from "@swc/helpers/_/_instanceof";
6
6
  import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
7
7
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
8
8
  import { ChunkExtractor } from "@loadable/server";
9
- import { attributesToString } from "../utils";
9
+ import { attributesToString, checkIsNode } from "../utils";
10
10
  var extname = function(uri) {
11
11
  if (typeof uri !== "string" || !uri.includes(".")) {
12
12
  return "";
@@ -61,10 +61,6 @@ var readAsset = function() {
61
61
  return _ref.apply(this, arguments);
62
62
  };
63
63
  }();
64
- var checkIsNode = function() {
65
- var _process_release;
66
- return typeof process !== "undefined" && ((_process_release = process.release) === null || _process_release === void 0 ? void 0 : _process_release.name) === "node";
67
- };
68
64
  var LoadableCollector = /* @__PURE__ */ function() {
69
65
  "use strict";
70
66
  function LoadableCollector2(options) {
@@ -184,7 +180,7 @@ var LoadableCollector = /* @__PURE__ */ function() {
184
180
  var script;
185
181
  return _ts_generator(this, function(_state2) {
186
182
  script = "<script".concat(attributes, ' src="').concat(chunk.url, '"></script>');
187
- if (checkIsInline(chunk, enableInlineScripts) && checkIsNode()) {
183
+ if (checkIsNode() && checkIsInline(chunk, enableInlineScripts)) {
188
184
  return [
189
185
  2,
190
186
  readAsset(chunk).then(function(content) {
@@ -244,7 +240,7 @@ var LoadableCollector = /* @__PURE__ */ function() {
244
240
  var link;
245
241
  return _ts_generator(this, function(_state2) {
246
242
  link = "<link".concat(atrributes, ' href="').concat(chunk.url, '" rel="stylesheet" />');
247
- if (checkIsInline(chunk, enableInlineStyles) && checkIsNode()) {
243
+ if (checkIsNode() && checkIsInline(chunk, enableInlineStyles)) {
248
244
  return [
249
245
  2,
250
246
  readAsset(chunk).then(function(content) {
@@ -10,7 +10,12 @@ function safeReplace(source, searchValue, replaceValue) {
10
10
  return replaceValue;
11
11
  });
12
12
  }
13
+ function checkIsNode() {
14
+ var _process_release;
15
+ return typeof process !== "undefined" && ((_process_release = process.release) === null || _process_release === void 0 ? void 0 : _process_release.name) === "node";
16
+ }
13
17
  export {
14
18
  attributesToString,
19
+ checkIsNode,
15
20
  safeReplace
16
21
  };
@@ -1,6 +1,6 @@
1
1
  const HEAD_REG_EXP = /<head(.|\n)*>(.|\n)*<\/head>/;
2
2
  function buildTemplate(template, callbacks) {
3
- return callbacks.reduce((template2, buildTemplateCb) => buildTemplateCb(template2), template);
3
+ return callbacks.reduce((promise, buildTemplateCb) => promise.then((template2) => buildTemplateCb(template2)), Promise.resolve(template));
4
4
  }
5
5
  export {
6
6
  HEAD_REG_EXP,
@@ -2,9 +2,26 @@ import ReactHelmet from "react-helmet";
2
2
  import { matchRoutes } from "@modern-js/runtime-utils/router";
3
3
  import helmetReplace from "../helmet";
4
4
  import { CHUNK_CSS_PLACEHOLDER } from "../constants";
5
- import { safeReplace } from "../utils";
5
+ import { checkIsNode, safeReplace } from "../utils";
6
6
  import { HEAD_REG_EXP, buildTemplate } from "./buildTemplate.share";
7
- function getHeadTemplate(beforeEntryTemplate, context) {
7
+ const readAsset = async (chunk) => {
8
+ const fs = await import("fs/promises");
9
+ const path = await import("path");
10
+ const filepath = path.join(__dirname, chunk);
11
+ return fs.readFile(filepath, "utf-8");
12
+ };
13
+ const checkIsInline = (chunk, enableInline) => {
14
+ if (process.env.NODE_ENV === "production") {
15
+ if (enableInline instanceof RegExp) {
16
+ return enableInline.test(chunk);
17
+ } else {
18
+ return Boolean(enableInline);
19
+ }
20
+ } else {
21
+ return false;
22
+ }
23
+ };
24
+ function getHeadTemplate(beforeEntryTemplate, context, pluginConfig) {
8
25
  const callbacks = [
9
26
  (headTemplate2) => {
10
27
  const helmetData = ReactHelmet.renderStatic();
@@ -18,9 +35,10 @@ function getHeadTemplate(beforeEntryTemplate, context) {
18
35
  return "";
19
36
  }
20
37
  return buildTemplate(headTemplate, callbacks);
21
- function injectCss(headTemplate2) {
22
- return safeReplace(headTemplate2, CHUNK_CSS_PLACEHOLDER, getCssChunks());
23
- function getCssChunks() {
38
+ async function injectCss(headTemplate2) {
39
+ const css = await getCssChunks();
40
+ return safeReplace(headTemplate2, CHUNK_CSS_PLACEHOLDER, css);
41
+ async function getCssChunks() {
24
42
  const { routeManifest, routerContext, routes } = context;
25
43
  if (!routeManifest || !routerContext || !routes) {
26
44
  return "";
@@ -42,15 +60,23 @@ function getHeadTemplate(beforeEntryTemplate, context) {
42
60
  }
43
61
  }
44
62
  });
45
- const styleLinks = cssChunks.map((chunk) => {
46
- return `<link href="${chunk}" rel="stylesheet" />`;
47
- });
48
- return `${styleLinks.join("")}`;
63
+ const { enableInlineStyles } = pluginConfig;
64
+ const styles = await Promise.all(cssChunks.map(async (chunk) => {
65
+ const link = `<link href="${chunk}" rel="stylesheet" />`;
66
+ if (checkIsNode() && checkIsInline(chunk, enableInlineStyles)) {
67
+ return readAsset(chunk).then((content) => `<style>${content}</style>`).catch((_) => {
68
+ return link;
69
+ });
70
+ } else {
71
+ return link;
72
+ }
73
+ }));
74
+ return `${styles.join("")}`;
49
75
  }
50
76
  }
51
77
  }
52
- function buildShellBeforeTemplate(beforeAppTemplate, context) {
53
- const headTemplate = getHeadTemplate(beforeAppTemplate, context);
78
+ async function buildShellBeforeTemplate(beforeAppTemplate, context, pluginConfig) {
79
+ const headTemplate = await getHeadTemplate(beforeAppTemplate, context, pluginConfig);
54
80
  return beforeAppTemplate.replace(HEAD_REG_EXP, headTemplate);
55
81
  }
56
82
  export {
@@ -3,7 +3,7 @@ import { run } from "@modern-js/runtime-utils/node";
3
3
  import { time } from "@modern-js/runtime-utils/time";
4
4
  import { SSRErrors, SSRTimings } from "../tracker";
5
5
  import renderToPipe from "./renderToPipe";
6
- const render = ({ App, context }) => {
6
+ const render = ({ App, context, config }) => {
7
7
  const { ssrContext } = context;
8
8
  if (!ssrContext) {
9
9
  throw new Error('The "ssrContext" must not be undefined, but received undefined');
@@ -16,7 +16,7 @@ const render = ({ App, context }) => {
16
16
  })
17
17
  });
18
18
  const { tracker } = ssrContext;
19
- const pipe = renderToPipe(rootElement, context, {
19
+ const pipe = renderToPipe(rootElement, context, config, {
20
20
  onShellReady() {
21
21
  const cost = end();
22
22
  tracker.trackTiming(SSRTimings.RENDER_SHELL, cost);
@@ -7,7 +7,7 @@ var ShellChunkStatus;
7
7
  ShellChunkStatus2[ShellChunkStatus2["START"] = 0] = "START";
8
8
  ShellChunkStatus2[ShellChunkStatus2["FINIESH"] = 1] = "FINIESH";
9
9
  })(ShellChunkStatus || (ShellChunkStatus = {}));
10
- function renderToPipe(rootElement, context, options) {
10
+ function renderToPipe(rootElement, context, pluginConfig, options) {
11
11
  let shellChunkStatus = 0;
12
12
  const { ssrContext } = context;
13
13
  const chunkVec = [];
@@ -22,41 +22,43 @@ function renderToPipe(rootElement, context, options) {
22
22
  ...options,
23
23
  nonce: ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.nonce,
24
24
  onShellReady() {
25
- var _options_onShellReady;
26
- const { shellAfter, shellBefore } = getTemplates(context, RenderLevel.SERVER_RENDER);
27
- options === null || options === void 0 ? void 0 : (_options_onShellReady = options.onShellReady) === null || _options_onShellReady === void 0 ? void 0 : _options_onShellReady.call(options);
28
- const injectableTransform = new Transform({
29
- transform(chunk, _encoding, callback) {
30
- try {
31
- if (shellChunkStatus !== 1) {
32
- chunkVec.push(chunk.toString());
33
- let concatedChunk = chunkVec.join("");
34
- if (concatedChunk.endsWith(ESCAPED_SHELL_STREAM_END_MARK)) {
35
- concatedChunk = concatedChunk.replace(ESCAPED_SHELL_STREAM_END_MARK, "");
36
- shellChunkStatus = 1;
37
- this.push(`${shellBefore}${concatedChunk}${shellAfter}`);
25
+ getTemplates(context, RenderLevel.SERVER_RENDER, pluginConfig).then(({ shellAfter, shellBefore }) => {
26
+ var _options_onShellReady;
27
+ options === null || options === void 0 ? void 0 : (_options_onShellReady = options.onShellReady) === null || _options_onShellReady === void 0 ? void 0 : _options_onShellReady.call(options);
28
+ const injectableTransform = new Transform({
29
+ transform(chunk, _encoding, callback) {
30
+ try {
31
+ if (shellChunkStatus !== 1) {
32
+ chunkVec.push(chunk.toString());
33
+ let concatedChunk = chunkVec.join("");
34
+ if (concatedChunk.endsWith(ESCAPED_SHELL_STREAM_END_MARK)) {
35
+ concatedChunk = concatedChunk.replace(ESCAPED_SHELL_STREAM_END_MARK, "");
36
+ shellChunkStatus = 1;
37
+ this.push(`${shellBefore}${concatedChunk}${shellAfter}`);
38
+ }
39
+ } else {
40
+ this.push(chunk);
41
+ }
42
+ callback();
43
+ } catch (e) {
44
+ if (e instanceof Error) {
45
+ callback(e);
46
+ } else {
47
+ callback(new Error("Received unkown error when streaming"));
38
48
  }
39
- } else {
40
- this.push(chunk);
41
- }
42
- callback();
43
- } catch (e) {
44
- if (e instanceof Error) {
45
- callback(e);
46
- } else {
47
- callback(new Error("Received unkown error when streaming"));
48
49
  }
49
50
  }
50
- }
51
+ });
52
+ resolve(pipe(injectableTransform).pipe(stream));
51
53
  });
52
- resolve(pipe(injectableTransform).pipe(stream));
53
54
  },
54
55
  onShellError(error) {
55
- var _options_onShellError;
56
- const { shellAfter, shellBefore } = getTemplates(context, RenderLevel.CLIENT_RENDER);
57
- const fallbackHtml = `${shellBefore}${shellAfter}`;
58
- resolve(fallbackHtml);
59
- options === null || options === void 0 ? void 0 : (_options_onShellError = options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(options, error);
56
+ getTemplates(context, RenderLevel.CLIENT_RENDER, pluginConfig).then(({ shellAfter, shellBefore }) => {
57
+ var _options_onShellError;
58
+ const fallbackHtml = `${shellBefore}${shellAfter}`;
59
+ resolve(fallbackHtml);
60
+ options === null || options === void 0 ? void 0 : (_options_onShellError = options.onShellError) === null || _options_onShellError === void 0 ? void 0 : _options_onShellError.call(options, error);
61
+ });
60
62
  }
61
63
  });
62
64
  });
@@ -7,7 +7,7 @@ var ShellChunkStatus;
7
7
  ShellChunkStatus2[ShellChunkStatus2["START"] = 0] = "START";
8
8
  ShellChunkStatus2[ShellChunkStatus2["FINIESH"] = 1] = "FINIESH";
9
9
  })(ShellChunkStatus || (ShellChunkStatus = {}));
10
- function renderToPipe(rootElement, context, options) {
10
+ function renderToPipe(rootElement, context, pluginConfig, options) {
11
11
  let shellChunkStatus = 0;
12
12
  const chunkVec = [];
13
13
  const { ssrContext } = context;
@@ -17,7 +17,7 @@ function renderToPipe(rootElement, context, options) {
17
17
  ({ renderToReadableStream } = require("react-dom/server"));
18
18
  } catch (e) {
19
19
  }
20
- const { shellAfter, shellBefore } = getTemplates(context, RenderLevel.SERVER_RENDER);
20
+ const { shellAfter, shellBefore } = await getTemplates(context, RenderLevel.SERVER_RENDER, pluginConfig);
21
21
  try {
22
22
  const readableOriginal = await renderToReadableStream(rootElement, {
23
23
  ...options,
@@ -56,7 +56,7 @@ function renderToPipe(rootElement, context, options) {
56
56
  return injectableStream;
57
57
  } catch (err) {
58
58
  ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.tracker.trackError(SSRErrors.RENDER_SHELL, err);
59
- const { shellAfter: shellAfter2, shellBefore: shellBefore2 } = getTemplates(context, RenderLevel.CLIENT_RENDER);
59
+ const { shellAfter: shellAfter2, shellBefore: shellBefore2 } = await getTemplates(context, RenderLevel.CLIENT_RENDER, pluginConfig);
60
60
  const fallbackHtml = `${shellBefore2}${shellAfter2}`;
61
61
  return fallbackHtml;
62
62
  }
@@ -1,11 +1,11 @@
1
1
  import { buildShellAfterTemplate } from "./buildTemplate.after";
2
2
  import { buildShellBeforeTemplate } from "./bulidTemplate.before";
3
3
  const HTML_SEPARATOR = "<!--<?- html ?>-->";
4
- const getTemplates = (context, renderLevel) => {
4
+ const getTemplates = async (context, renderLevel, pluginConfig) => {
5
5
  const { ssrContext } = context;
6
6
  const [beforeAppTemplate = "", afterAppHtmlTemplate = ""] = ssrContext.template.split(HTML_SEPARATOR) || [];
7
- const builtBeforeTemplate = buildShellBeforeTemplate(beforeAppTemplate, context);
8
- const builtAfterTemplate = buildShellAfterTemplate(afterAppHtmlTemplate, {
7
+ const builtBeforeTemplate = await buildShellBeforeTemplate(beforeAppTemplate, context, pluginConfig);
8
+ const builtAfterTemplate = await buildShellAfterTemplate(afterAppHtmlTemplate, {
9
9
  context,
10
10
  renderLevel
11
11
  });
@@ -1,6 +1,6 @@
1
1
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
2
  import { ChunkExtractor } from "@loadable/server";
3
- import { attributesToString } from "../utils";
3
+ import { attributesToString, checkIsNode } from "../utils";
4
4
  const extname = (uri) => {
5
5
  if (typeof uri !== "string" || !uri.includes(".")) {
6
6
  return "";
@@ -25,10 +25,6 @@ const readAsset = async (chunk) => {
25
25
  const filepath = path.resolve(__dirname, chunk.filename);
26
26
  return fs.readFile(filepath, "utf-8");
27
27
  };
28
- const checkIsNode = () => {
29
- var _process_release;
30
- return typeof process !== "undefined" && ((_process_release = process.release) === null || _process_release === void 0 ? void 0 : _process_release.name) === "node";
31
- };
32
28
  class LoadableCollector {
33
29
  get existsAssets() {
34
30
  var _routeManifest_routeAssets_entryName, _routeManifest_routeAssets;
@@ -88,7 +84,7 @@ class LoadableCollector {
88
84
  return !jsChunkReg.test(template) && !((_this_existsAssets = this.existsAssets) === null || _this_existsAssets === void 0 ? void 0 : _this_existsAssets.includes(chunk.path));
89
85
  }).map(async (chunk) => {
90
86
  const script = `<script${attributes} src="${chunk.url}"></script>`;
91
- if (checkIsInline(chunk, enableInlineScripts) && checkIsNode()) {
87
+ if (checkIsNode() && checkIsInline(chunk, enableInlineScripts)) {
92
88
  return readAsset(chunk).then((content) => `<script>${content}</script>`).catch((_) => {
93
89
  return script;
94
90
  });
@@ -107,7 +103,7 @@ class LoadableCollector {
107
103
  return !cssChunkReg.test(template) && !((_this_existsAssets = this.existsAssets) === null || _this_existsAssets === void 0 ? void 0 : _this_existsAssets.includes(chunk.path));
108
104
  }).map(async (chunk) => {
109
105
  const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
110
- if (checkIsInline(chunk, enableInlineStyles) && checkIsNode()) {
106
+ if (checkIsNode() && checkIsInline(chunk, enableInlineStyles)) {
111
107
  return readAsset(chunk).then((content) => `<style>${content}</style>`).catch((_) => {
112
108
  return link;
113
109
  });
@@ -6,7 +6,12 @@ function attributesToString(attributes) {
6
6
  function safeReplace(source, searchValue, replaceValue) {
7
7
  return source.replace(searchValue, () => replaceValue);
8
8
  }
9
+ function checkIsNode() {
10
+ var _process_release;
11
+ return typeof process !== "undefined" && ((_process_release = process.release) === null || _process_release === void 0 ? void 0 : _process_release.name) === "node";
12
+ }
9
13
  export {
10
14
  attributesToString,
15
+ checkIsNode,
11
16
  safeReplace
12
17
  };
@@ -3,5 +3,5 @@ type BuildShellAfterTemplateOptions = {
3
3
  context: RuntimeContext;
4
4
  renderLevel: RenderLevel;
5
5
  };
6
- export declare function buildShellAfterTemplate(afterAppTemplate: string, options: BuildShellAfterTemplateOptions): string;
6
+ export declare function buildShellAfterTemplate(afterAppTemplate: string, options: BuildShellAfterTemplateOptions): Promise<string>;
7
7
  export {};
@@ -1,3 +1,3 @@
1
1
  export declare const HEAD_REG_EXP: RegExp;
2
- export type BuildTemplateCb = (headTemplate: string) => string;
3
- export declare function buildTemplate(template: string, callbacks: BuildTemplateCb[]): string;
2
+ export type BuildTemplateCb = (headTemplate: string) => string | Promise<string>;
3
+ export declare function buildTemplate(template: string, callbacks: BuildTemplateCb[]): Promise<string>;
@@ -1,2 +1,2 @@
1
- import { RuntimeContext } from '../types';
2
- export declare function buildShellBeforeTemplate(beforeAppTemplate: string, context: RuntimeContext): string;
1
+ import { RuntimeContext, SSRPluginConfig } from '../types';
2
+ export declare function buildShellBeforeTemplate(beforeAppTemplate: string, context: RuntimeContext, pluginConfig: SSRPluginConfig): Promise<string>;
@@ -1,3 +1,3 @@
1
1
  /// <reference types="node" />
2
2
  import { ServerRenderOptions } from '../types';
3
- export declare const render: ({ App, context }: ServerRenderOptions) => Promise<import("./renderToPipe").Pipe<import("stream").Writable>>;
3
+ export declare const render: ({ App, context, config }: ServerRenderOptions) => Promise<import("./renderToPipe").Pipe<import("stream").Writable>>;
@@ -2,7 +2,7 @@
2
2
  /// <reference types="react" />
3
3
  import { Writable } from 'stream';
4
4
  import type { RenderToPipeableStreamOptions } from 'react-dom/server';
5
- import { RuntimeContext } from '../types';
5
+ import { RuntimeContext, SSRPluginConfig } from '../types';
6
6
  export type Pipe<T extends Writable> = (output: T) => Promise<T | string>;
7
- declare function renderToPipe(rootElement: React.ReactElement, context: RuntimeContext, options?: RenderToPipeableStreamOptions): Pipe<Writable>;
7
+ declare function renderToPipe(rootElement: React.ReactElement, context: RuntimeContext, pluginConfig: SSRPluginConfig, options?: RenderToPipeableStreamOptions): Pipe<Writable>;
8
8
  export default renderToPipe;
@@ -2,7 +2,7 @@
2
2
  /// <reference types="react" />
3
3
  import type { Writable } from 'stream';
4
4
  import type { RenderToReadableStreamOptions } from 'react-dom/server';
5
- import { RuntimeContext } from '../types';
5
+ import { RuntimeContext, SSRPluginConfig } from '../types';
6
6
  export type Pipe<T extends Writable> = (output: T) => Promise<T | string>;
7
- declare function renderToPipe(rootElement: React.ReactElement, context: RuntimeContext, options?: RenderToReadableStreamOptions): Promise<string | ReadableStream<any>>;
7
+ declare function renderToPipe(rootElement: React.ReactElement, context: RuntimeContext, pluginConfig: SSRPluginConfig, options?: RenderToReadableStreamOptions): Promise<string | ReadableStream<any>>;
8
8
  export default renderToPipe;
@@ -1,6 +1,6 @@
1
- import { RenderLevel, RuntimeContext } from '../types';
1
+ import { RenderLevel, RuntimeContext, SSRPluginConfig } from '../types';
2
2
  export type InjectTemplate = {
3
3
  shellBefore: string;
4
4
  shellAfter: string;
5
5
  };
6
- export declare const getTemplates: (context: RuntimeContext, renderLevel: RenderLevel) => InjectTemplate;
6
+ export declare const getTemplates: (context: RuntimeContext, renderLevel: RenderLevel, pluginConfig: SSRPluginConfig) => Promise<InjectTemplate>;
@@ -6,3 +6,4 @@ export declare function attributesToString(attributes: Record<string, any>): str
6
6
  * @returns
7
7
  */
8
8
  export declare function safeReplace(source: string, searchValue: string | RegExp, replaceValue: string): string;
9
+ export declare function checkIsNode(): boolean;
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.43.0",
18
+ "version": "2.44.0",
19
19
  "engines": {
20
20
  "node": ">=14.17.6"
21
21
  },
@@ -171,10 +171,10 @@
171
171
  "react-side-effect": "^2.1.1",
172
172
  "styled-components": "^5.3.1",
173
173
  "@swc/helpers": "0.5.3",
174
- "@modern-js/plugin": "2.43.0",
175
- "@modern-js/runtime-utils": "2.43.0",
176
- "@modern-js/utils": "2.43.0",
177
- "@modern-js/types": "2.43.0"
174
+ "@modern-js/types": "2.44.0",
175
+ "@modern-js/utils": "2.44.0",
176
+ "@modern-js/runtime-utils": "2.44.0",
177
+ "@modern-js/plugin": "2.44.0"
178
178
  },
179
179
  "peerDependencies": {
180
180
  "react": ">=17",
@@ -195,11 +195,11 @@
195
195
  "ts-jest": "^29.1.0",
196
196
  "typescript": "^5",
197
197
  "webpack": "^5.89.0",
198
- "@modern-js/app-tools": "2.43.0",
199
- "@modern-js/server-core": "2.43.0",
200
- "@scripts/jest-config": "2.43.0",
201
- "@modern-js/core": "2.43.0",
202
- "@scripts/build": "2.43.0"
198
+ "@modern-js/app-tools": "2.44.0",
199
+ "@modern-js/core": "2.44.0",
200
+ "@modern-js/server-core": "2.44.0",
201
+ "@scripts/build": "2.44.0",
202
+ "@scripts/jest-config": "2.44.0"
203
203
  },
204
204
  "sideEffects": false,
205
205
  "publishConfig": {