@modern-js/runtime 2.25.1 → 2.26.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 (29) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/cjs/document/Body.js +2 -1
  3. package/dist/cjs/document/Head.js +2 -1
  4. package/dist/cjs/document/Root.js +14 -8
  5. package/dist/cjs/router/runtime/plugin.js +19 -1
  6. package/dist/cjs/ssr/cli/index.js +1 -1
  7. package/dist/cjs/ssr/serverRender/renderToStream/renderToPipe.worker.js +3 -4
  8. package/dist/cjs/ssr/serverRender/renderToString/entry.js +4 -1
  9. package/dist/cjs/ssr/serverRender/renderToString/loadable.js +6 -3
  10. package/dist/esm/document/Body.js +8 -3
  11. package/dist/esm/document/Head.js +8 -3
  12. package/dist/esm/document/Root.js +20 -8
  13. package/dist/esm/router/runtime/plugin.js +23 -1
  14. package/dist/esm/ssr/serverRender/renderToStream/renderToPipe.worker.js +3 -4
  15. package/dist/esm/ssr/serverRender/renderToString/entry.js +4 -1
  16. package/dist/esm/ssr/serverRender/renderToString/loadable.js +6 -3
  17. package/dist/esm-node/document/Body.js +2 -1
  18. package/dist/esm-node/document/Head.js +2 -1
  19. package/dist/esm-node/document/Root.js +14 -8
  20. package/dist/esm-node/router/runtime/plugin.js +19 -1
  21. package/dist/esm-node/ssr/cli/index.js +1 -1
  22. package/dist/esm-node/ssr/serverRender/renderToStream/renderToPipe.worker.js +3 -4
  23. package/dist/esm-node/ssr/serverRender/renderToString/entry.js +4 -1
  24. package/dist/esm-node/ssr/serverRender/renderToString/loadable.js +6 -3
  25. package/dist/types/runtimeContext.d.ts +8 -0
  26. package/dist/types/ssr/serverRender/renderToString/entry.d.ts +1 -0
  27. package/dist/types/ssr/serverRender/renderToString/type.d.ts +1 -0
  28. package/package.json +13 -13
  29. package/types/model.d.ts +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @modern-js/runtime
2
2
 
3
+ ## 2.26.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 22acfda: feat: support unstable_getBlockNavState
8
+ feat: 支持 unstable_getBlockNavState
9
+
10
+ ### Patch Changes
11
+
12
+ - 64a51c4: fix(plugin-runtime): we should not repeatly registe the script, if template has it.
13
+ fix(plugin-runtime): 如果模版中已经有了,我们不应该重复添加 script 链接
14
+ - 1586774: feat: add support for origin properties in document
15
+ feat: 为 document 增加原始属性透传
16
+ - 73c592d: fix: should define remixRouter property when the property does not exist
17
+ fix: 应该仅当属性不存在时,定义 remixRouter
18
+ - 5c2dbb3: refactor: use import syntax for reduck plugin types
19
+ refactor: 使用 import 语法加载 reduck 插件的类型文件
20
+ - @modern-js/plugin@2.26.0
21
+ - @modern-js/types@2.26.0
22
+ - @modern-js/utils@2.26.0
23
+
24
+ ## 2.25.2
25
+
26
+ ### Patch Changes
27
+
28
+ - 272646c: feat(builder): bump webpack v5.88, support top level await
29
+
30
+ feat(builder): 升级 webpack v5.88, 支持 top level await
31
+
32
+ - e8a90f3: fix(ssr-plugin): worker streaming ssr douable enqueue the value so that ssr error
33
+ fix(ssr-plugin): worker streaming ssr 重复 enqueue chunk 值导致 ssr 错误
34
+ - Updated dependencies [63d8247]
35
+ - Updated dependencies [6651684]
36
+ - Updated dependencies [272646c]
37
+ - Updated dependencies [358ed24]
38
+ - @modern-js/utils@2.25.2
39
+ - @modern-js/plugin@2.25.2
40
+ - @modern-js/types@2.25.2
41
+
3
42
  ## 2.25.1
4
43
 
5
44
  ### Patch Changes
@@ -16,8 +16,9 @@ const _DocumentStructureContext = require("./DocumentStructureContext");
16
16
  const _Root = require("./Root");
17
17
  function Body(props) {
18
18
  const { hasSetRoot } = (0, _react.useContext)(_DocumentStructureContext.DocumentStructureContext);
19
- const { children } = props;
19
+ const { children, ...rest } = props;
20
20
  return /* @__PURE__ */ (0, _jsxruntime.jsxs)("body", {
21
+ ...rest,
21
22
  children: [
22
23
  hasSetRoot ? null : /* @__PURE__ */ (0, _jsxruntime.jsx)(_Root.DefaultRoot, {}),
23
24
  children,
@@ -26,8 +26,9 @@ const _Links = require("./Links");
26
26
  const _constants = require("./constants");
27
27
  function Head(props) {
28
28
  const { hasSetScripts, hasSetLinks } = (0, _react.useContext)(_DocumentStructureContext.DocumentStructureContext);
29
- const { children } = props;
29
+ const { children, ...rest } = props;
30
30
  return /* @__PURE__ */ (0, _jsxruntime.jsxs)("head", {
31
+ ...rest,
31
32
  children: [
32
33
  `${_constants.DOCUMENT_META_PLACEHOLDER}`,
33
34
  !hasSetLinks && /* @__PURE__ */ (0, _jsxruntime.jsx)(_Links.Links, {}),
@@ -20,18 +20,24 @@ _export(exports, {
20
20
  const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
21
21
  const _jsxruntime = require("react/jsx-runtime");
22
22
  const _react = /* @__PURE__ */ _interop_require_wildcard._(require("react"));
23
+ const _lodash = require("@modern-js/utils/lodash");
23
24
  const _DocumentContext = require("./DocumentContext");
24
25
  const _constants = require("./constants");
25
26
  function Root(props) {
26
- const { rootId, children } = props;
27
+ const { rootId, children, ...rest } = props;
28
+ const legalProperties = (0, _lodash.omit)(rest, "id");
27
29
  const { templateParams: { mountId = "root" } } = (0, _react.useContext)(_DocumentContext.DocumentContext);
28
- return /* @__PURE__ */ (0, _jsxruntime.jsxs)("div", {
29
- id: `${rootId || mountId}`,
30
- children: [
31
- `${_constants.DOCUMENT_SSR_PLACEHOLDER}`,
32
- children
33
- ]
34
- });
30
+ return (
31
+ // in case for properities order not keep
32
+ /* @__PURE__ */ (0, _jsxruntime.jsxs)("div", {
33
+ id: `${rootId || mountId}`,
34
+ ...legalProperties,
35
+ children: [
36
+ `${_constants.DOCUMENT_SSR_PLACEHOLDER}`,
37
+ children
38
+ ]
39
+ })
40
+ );
35
41
  }
36
42
  function DefaultRoot(props) {
37
43
  const { templateParams: { mountId = "root" } } = (0, _react.useContext)(_DocumentContext.DocumentContext);
@@ -105,7 +105,25 @@ const routerPlugin = ({ serverBase = [], supportHtml5History = true, basename =
105
105
  hydrationData
106
106
  });
107
107
  const runtimeContext = (0, _react.useContext)(_core.RuntimeReactContext);
108
- runtimeContext.remixRouter = router;
108
+ if (!runtimeContext.remixRouter) {
109
+ Object.defineProperty(runtimeContext, "remixRouter", {
110
+ get() {
111
+ return router;
112
+ }
113
+ });
114
+ }
115
+ const originSubscribe = router.subscribe;
116
+ router.subscribe = (listener) => {
117
+ const wrapedListener = (...args) => {
118
+ const getBlockNavState = runtimeContext.unstable_getBlockNavState;
119
+ const blockRoute = getBlockNavState ? getBlockNavState() : false;
120
+ if (blockRoute) {
121
+ return;
122
+ }
123
+ return listener(...args);
124
+ };
125
+ return originSubscribe(wrapedListener);
126
+ };
109
127
  return /* @__PURE__ */ (0, _jsxruntime.jsx)(App, {
110
128
  ...props,
111
129
  children: /* @__PURE__ */ (0, _jsxruntime.jsx)(_router.RouterProvider, {
@@ -114,7 +114,7 @@ const ssrPlugin = () => {
114
114
  throw new Error(`router v5 plugin doesn't support streaming SSR, check your config 'runtime.router'`);
115
115
  }
116
116
  if (fileSystemRoutes && !entrypoint.nestedRoutesEntry) {
117
- throw new Error(`You should switch to file-system based router to support streaming SSR.`);
117
+ throw new Error("You should switch to file-system based router to support streaming SSR.");
118
118
  }
119
119
  }
120
120
  const useSSG = (0, _utils.isSSGEntry)(userConfig, entryName, entrypoints);
@@ -33,8 +33,8 @@ function renderToPipe(rootElement, context, options) {
33
33
  nonce: ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.nonce,
34
34
  onError(error) {
35
35
  var _options_onError;
36
- ssrContext.logger.error("An error occurs during streaming SSR", error);
37
- ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
36
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.logger.error("An error occurs during streaming SSR", error);
37
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
38
38
  options === null || options === void 0 ? void 0 : (_options_onError = options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(options, error);
39
39
  }
40
40
  });
@@ -56,7 +56,6 @@ function renderToPipe(rootElement, context, options) {
56
56
  shellChunkStatus = ShellChunkStatus.FINIESH;
57
57
  controller.enqueue(encodeForWebStream(`${shellBefore}${concatedChunk}${shellAfter}`));
58
58
  }
59
- controller.enqueue(encodeForWebStream(concatedChunk));
60
59
  } else {
61
60
  controller.enqueue(value);
62
61
  }
@@ -67,7 +66,7 @@ function renderToPipe(rootElement, context, options) {
67
66
  });
68
67
  return injectableStream;
69
68
  } catch (err) {
70
- ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
69
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
71
70
  const { shellAfter: shellAfter2, shellBefore: shellBefore2 } = (0, _template.getTemplates)(context, _types.RenderLevel.CLIENT_RENDER);
72
71
  const fallbackHtml = `${shellBefore2}${shellAfter2}`;
73
72
  return fallbackHtml;
@@ -112,7 +112,8 @@ class Entry {
112
112
  result: this.result,
113
113
  entryName: this.entryName,
114
114
  config: this.pluginConfig,
115
- nonce: this.nonce
115
+ nonce: this.nonce,
116
+ template: this.template
116
117
  };
117
118
  html = (0, _reduce.reduce)(App, renderContext, [
118
119
  _styledComponent.toHtml,
@@ -151,6 +152,7 @@ class Entry {
151
152
  _define_property._(this, "result", void 0);
152
153
  _define_property._(this, "metrics", void 0);
153
154
  _define_property._(this, "logger", void 0);
155
+ _define_property._(this, "template", void 0);
154
156
  _define_property._(this, "App", void 0);
155
157
  _define_property._(this, "fragments", void 0);
156
158
  _define_property._(this, "pluginConfig", void 0);
@@ -159,6 +161,7 @@ class Entry {
159
161
  const { ctx, config } = options;
160
162
  const { entryName, template, request: { host }, nonce } = ctx;
161
163
  this.fragments = (0, _template.toFragments)(template, entryName);
164
+ this.template = template;
162
165
  this.entryName = entryName;
163
166
  this.host = host;
164
167
  this.App = options.App;
@@ -47,9 +47,12 @@ const toHtml = (jsx, renderer, next) => {
47
47
  default:
48
48
  }
49
49
  if (fileType === "js") {
50
- attributes.nonce = nonce;
51
- const attrsStr = (0, _utils.attributesToString)(attributes);
52
- chunksMap[fileType] += `<script${attrsStr} src="${v.url}"></script>`;
50
+ const jsChunkReg = new RegExp(`<script .*src="${v.url}".*>`);
51
+ if (!jsChunkReg.test(renderer.template)) {
52
+ attributes.nonce = nonce;
53
+ const attrsStr = (0, _utils.attributesToString)(attributes);
54
+ chunksMap[fileType] += `<script${attrsStr} src="${v.url}"></script>`;
55
+ }
53
56
  } else if (fileType === "css") {
54
57
  const attrsStr = (0, _utils.attributesToString)(attributes);
55
58
  chunksMap[fileType] += `<link${attrsStr} href="${v.url}" rel="stylesheet" />`;
@@ -1,3 +1,6 @@
1
+ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
+ import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
3
+ import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
1
4
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
5
  import { useContext } from "react";
3
6
  import { DOCUMENT_CHUNKSMAP_PLACEHOLDER, DOCUMENT_SSRDATASCRIPT_PLACEHOLDER } from "./constants";
@@ -5,13 +8,15 @@ import { DocumentStructureContext } from "./DocumentStructureContext";
5
8
  import { DefaultRoot } from "./Root";
6
9
  export function Body(props) {
7
10
  var hasSetRoot = useContext(DocumentStructureContext).hasSetRoot;
8
- var children = props.children;
9
- return /* @__PURE__ */ _jsxs("body", {
11
+ var children = props.children, rest = _object_without_properties(props, [
12
+ "children"
13
+ ]);
14
+ return /* @__PURE__ */ _jsxs("body", _object_spread_props(_object_spread({}, rest), {
10
15
  children: [
11
16
  hasSetRoot ? null : /* @__PURE__ */ _jsx(DefaultRoot, {}),
12
17
  children,
13
18
  "".concat(DOCUMENT_CHUNKSMAP_PLACEHOLDER),
14
19
  "".concat(DOCUMENT_SSRDATASCRIPT_PLACEHOLDER)
15
20
  ]
16
- });
21
+ }));
17
22
  }
@@ -1,3 +1,6 @@
1
+ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
+ import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
3
+ import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
1
4
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
5
  import { useContext } from "react";
3
6
  import { DocumentStructureContext } from "./DocumentStructureContext";
@@ -6,15 +9,17 @@ import { Links } from "./Links";
6
9
  import { DOCUMENT_META_PLACEHOLDER } from "./constants";
7
10
  export function Head(props) {
8
11
  var _useContext = useContext(DocumentStructureContext), hasSetScripts = _useContext.hasSetScripts, hasSetLinks = _useContext.hasSetLinks;
9
- var children = props.children;
10
- return /* @__PURE__ */ _jsxs("head", {
12
+ var children = props.children, rest = _object_without_properties(props, [
13
+ "children"
14
+ ]);
15
+ return /* @__PURE__ */ _jsxs("head", _object_spread_props(_object_spread({}, rest), {
11
16
  children: [
12
17
  "".concat(DOCUMENT_META_PLACEHOLDER),
13
18
  !hasSetLinks && /* @__PURE__ */ _jsx(Links, {}),
14
19
  !hasSetScripts && /* @__PURE__ */ _jsx(Scripts, {}),
15
20
  children
16
21
  ]
17
- });
22
+ }));
18
23
  }
19
24
  export function DefaultHead() {
20
25
  return /* @__PURE__ */ _jsx("head", {
@@ -1,17 +1,29 @@
1
+ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
+ import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
3
+ import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
1
4
  import { jsxs as _jsxs } from "react/jsx-runtime";
2
5
  import { useContext } from "react";
6
+ import { omit } from "@modern-js/utils/lodash";
3
7
  import { DocumentContext } from "./DocumentContext";
4
8
  import { DOCUMENT_SSR_PLACEHOLDER } from "./constants";
5
9
  export function Root(props) {
6
- var rootId = props.rootId, children = props.children;
10
+ var rootId = props.rootId, children = props.children, rest = _object_without_properties(props, [
11
+ "rootId",
12
+ "children"
13
+ ]);
14
+ var legalProperties = omit(rest, "id");
7
15
  var _useContext = useContext(DocumentContext), _useContext_templateParams = _useContext.templateParams, _useContext_templateParams_mountId = _useContext_templateParams.mountId, mountId = _useContext_templateParams_mountId === void 0 ? "root" : _useContext_templateParams_mountId;
8
- return /* @__PURE__ */ _jsxs("div", {
9
- id: "".concat(rootId || mountId),
10
- children: [
11
- "".concat(DOCUMENT_SSR_PLACEHOLDER),
12
- children
13
- ]
14
- });
16
+ return (
17
+ // in case for properities order not keep
18
+ /* @__PURE__ */ _jsxs("div", _object_spread_props(_object_spread({
19
+ id: "".concat(rootId || mountId)
20
+ }, legalProperties), {
21
+ children: [
22
+ "".concat(DOCUMENT_SSR_PLACEHOLDER),
23
+ children
24
+ ]
25
+ }))
26
+ );
15
27
  }
16
28
  export function DefaultRoot(props) {
17
29
  var _useContext = useContext(DocumentContext), _useContext_templateParams = _useContext.templateParams, _useContext_templateParams_mountId = _useContext_templateParams.mountId, mountId = _useContext_templateParams_mountId === void 0 ? "root" : _useContext_templateParams_mountId;
@@ -1,5 +1,6 @@
1
1
  import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
2
  import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
3
+ import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
3
4
  import { jsx as _jsx } from "react/jsx-runtime";
4
5
  import { useContext } from "react";
5
6
  import { createBrowserRouter, createHashRouter, RouterProvider, createRoutesFromElements, useMatches, useLocation } from "@modern-js/utils/runtime/router";
@@ -86,7 +87,28 @@ export var routerPlugin = function(param) {
86
87
  hydrationData: hydrationData
87
88
  });
88
89
  var runtimeContext = useContext(RuntimeReactContext);
89
- runtimeContext.remixRouter = router;
90
+ if (!runtimeContext.remixRouter) {
91
+ Object.defineProperty(runtimeContext, "remixRouter", {
92
+ get: function get() {
93
+ return router;
94
+ }
95
+ });
96
+ }
97
+ var originSubscribe = router.subscribe;
98
+ router.subscribe = function(listener) {
99
+ var wrapedListener = function() {
100
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
101
+ args[_key] = arguments[_key];
102
+ }
103
+ var getBlockNavState = runtimeContext.unstable_getBlockNavState;
104
+ var blockRoute = getBlockNavState ? getBlockNavState() : false;
105
+ if (blockRoute) {
106
+ return;
107
+ }
108
+ return listener.apply(void 0, _to_consumable_array(args));
109
+ };
110
+ return originSubscribe(wrapedListener);
111
+ };
90
112
  return /* @__PURE__ */ _jsx(App, _object_spread_props(_object_spread({}, props), {
91
113
  children: /* @__PURE__ */ _jsx(RouterProvider, {
92
114
  router: router
@@ -39,8 +39,8 @@ function renderToPipe(rootElement, context, options) {
39
39
  nonce: ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.nonce,
40
40
  onError: function onError(error) {
41
41
  var _options_onError;
42
- ssrContext.logger.error("An error occurs during streaming SSR", error);
43
- ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
42
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.logger.error("An error occurs during streaming SSR", error);
43
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
44
44
  options === null || options === void 0 ? void 0 : (_options_onError = options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(options, error);
45
45
  }
46
46
  }))
@@ -80,7 +80,6 @@ function renderToPipe(rootElement, context, options) {
80
80
  shellChunkStatus = ShellChunkStatus.FINIESH;
81
81
  controller.enqueue(encodeForWebStream("".concat(shellBefore).concat(concatedChunk).concat(shellAfter)));
82
82
  }
83
- controller.enqueue(encodeForWebStream(concatedChunk));
84
83
  } else {
85
84
  controller.enqueue(value);
86
85
  }
@@ -102,7 +101,7 @@ function renderToPipe(rootElement, context, options) {
102
101
  ];
103
102
  case 3:
104
103
  err = _state.sent();
105
- ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
104
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
106
105
  _getTemplates1 = getTemplates(context, RenderLevel.CLIENT_RENDER), shellAfter1 = _getTemplates1.shellAfter, shellBefore1 = _getTemplates1.shellBefore;
107
106
  fallbackHtml = "".concat(shellBefore1).concat(shellAfter1);
108
107
  return [
@@ -45,6 +45,7 @@ var Entry = /* @__PURE__ */ function() {
45
45
  _define_property(this, "result", void 0);
46
46
  _define_property(this, "metrics", void 0);
47
47
  _define_property(this, "logger", void 0);
48
+ _define_property(this, "template", void 0);
48
49
  _define_property(this, "App", void 0);
49
50
  _define_property(this, "fragments", void 0);
50
51
  _define_property(this, "pluginConfig", void 0);
@@ -53,6 +54,7 @@ var Entry = /* @__PURE__ */ function() {
53
54
  var ctx = options.ctx, config = options.config;
54
55
  var entryName = ctx.entryName, template = ctx.template, host = ctx.request.host, nonce = ctx.nonce;
55
56
  this.fragments = toFragments(template, entryName);
57
+ this.template = template;
56
58
  this.entryName = entryName;
57
59
  this.host = host;
58
60
  this.App = options.App;
@@ -218,7 +220,8 @@ var Entry = /* @__PURE__ */ function() {
218
220
  result: this.result,
219
221
  entryName: this.entryName,
220
222
  config: this.pluginConfig,
221
- nonce: this.nonce
223
+ nonce: this.nonce,
224
+ template: this.template
222
225
  };
223
226
  html = reduce(App, renderContext, [
224
227
  styledComponentRenderer.toHtml,
@@ -40,9 +40,12 @@ export var toHtml = function(jsx, renderer, next) {
40
40
  default:
41
41
  }
42
42
  if (fileType === "js") {
43
- attributes.nonce = nonce;
44
- var attrsStr = attributesToString(attributes);
45
- chunksMap[fileType] += "<script".concat(attrsStr, ' src="').concat(v.url, '"></script>');
43
+ var jsChunkReg = new RegExp('<script .*src="'.concat(v.url, '".*>'));
44
+ if (!jsChunkReg.test(renderer.template)) {
45
+ attributes.nonce = nonce;
46
+ var attrsStr = attributesToString(attributes);
47
+ chunksMap[fileType] += "<script".concat(attrsStr, ' src="').concat(v.url, '"></script>');
48
+ }
46
49
  } else if (fileType === "css") {
47
50
  var attrsStr1 = attributesToString(attributes);
48
51
  chunksMap[fileType] += "<link".concat(attrsStr1, ' href="').concat(v.url, '" rel="stylesheet" />');
@@ -5,8 +5,9 @@ import { DocumentStructureContext } from "./DocumentStructureContext";
5
5
  import { DefaultRoot } from "./Root";
6
6
  export function Body(props) {
7
7
  const { hasSetRoot } = useContext(DocumentStructureContext);
8
- const { children } = props;
8
+ const { children, ...rest } = props;
9
9
  return /* @__PURE__ */ _jsxs("body", {
10
+ ...rest,
10
11
  children: [
11
12
  hasSetRoot ? null : /* @__PURE__ */ _jsx(DefaultRoot, {}),
12
13
  children,
@@ -6,8 +6,9 @@ import { Links } from "./Links";
6
6
  import { DOCUMENT_META_PLACEHOLDER } from "./constants";
7
7
  export function Head(props) {
8
8
  const { hasSetScripts, hasSetLinks } = useContext(DocumentStructureContext);
9
- const { children } = props;
9
+ const { children, ...rest } = props;
10
10
  return /* @__PURE__ */ _jsxs("head", {
11
+ ...rest,
11
12
  children: [
12
13
  `${DOCUMENT_META_PLACEHOLDER}`,
13
14
  !hasSetLinks && /* @__PURE__ */ _jsx(Links, {}),
@@ -1,17 +1,23 @@
1
1
  import { jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useContext } from "react";
3
+ import { omit } from "@modern-js/utils/lodash";
3
4
  import { DocumentContext } from "./DocumentContext";
4
5
  import { DOCUMENT_SSR_PLACEHOLDER } from "./constants";
5
6
  export function Root(props) {
6
- const { rootId, children } = props;
7
+ const { rootId, children, ...rest } = props;
8
+ const legalProperties = omit(rest, "id");
7
9
  const { templateParams: { mountId = "root" } } = useContext(DocumentContext);
8
- return /* @__PURE__ */ _jsxs("div", {
9
- id: `${rootId || mountId}`,
10
- children: [
11
- `${DOCUMENT_SSR_PLACEHOLDER}`,
12
- children
13
- ]
14
- });
10
+ return (
11
+ // in case for properities order not keep
12
+ /* @__PURE__ */ _jsxs("div", {
13
+ id: `${rootId || mountId}`,
14
+ ...legalProperties,
15
+ children: [
16
+ `${DOCUMENT_SSR_PLACEHOLDER}`,
17
+ children
18
+ ]
19
+ })
20
+ );
15
21
  }
16
22
  export function DefaultRoot(props) {
17
23
  const { templateParams: { mountId = "root" } } = useContext(DocumentContext);
@@ -78,7 +78,25 @@ export const routerPlugin = ({ serverBase = [], supportHtml5History = true, base
78
78
  hydrationData
79
79
  });
80
80
  const runtimeContext = useContext(RuntimeReactContext);
81
- runtimeContext.remixRouter = router;
81
+ if (!runtimeContext.remixRouter) {
82
+ Object.defineProperty(runtimeContext, "remixRouter", {
83
+ get() {
84
+ return router;
85
+ }
86
+ });
87
+ }
88
+ const originSubscribe = router.subscribe;
89
+ router.subscribe = (listener) => {
90
+ const wrapedListener = (...args) => {
91
+ const getBlockNavState = runtimeContext.unstable_getBlockNavState;
92
+ const blockRoute = getBlockNavState ? getBlockNavState() : false;
93
+ if (blockRoute) {
94
+ return;
95
+ }
96
+ return listener(...args);
97
+ };
98
+ return originSubscribe(wrapedListener);
99
+ };
82
100
  return /* @__PURE__ */ _jsx(App, {
83
101
  ...props,
84
102
  children: /* @__PURE__ */ _jsx(RouterProvider, {
@@ -94,7 +94,7 @@ export const ssrPlugin = () => {
94
94
  throw new Error(`router v5 plugin doesn't support streaming SSR, check your config 'runtime.router'`);
95
95
  }
96
96
  if (fileSystemRoutes && !entrypoint.nestedRoutesEntry) {
97
- throw new Error(`You should switch to file-system based router to support streaming SSR.`);
97
+ throw new Error("You should switch to file-system based router to support streaming SSR.");
98
98
  }
99
99
  }
100
100
  const useSSG = isSSGEntry(userConfig, entryName, entrypoints);
@@ -23,8 +23,8 @@ function renderToPipe(rootElement, context, options) {
23
23
  nonce: ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.nonce,
24
24
  onError(error) {
25
25
  var _options_onError;
26
- ssrContext.logger.error("An error occurs during streaming SSR", error);
27
- ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
26
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.logger.error("An error occurs during streaming SSR", error);
27
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.metrics.emitCounter("app.render.streaming.error", 1);
28
28
  options === null || options === void 0 ? void 0 : (_options_onError = options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(options, error);
29
29
  }
30
30
  });
@@ -46,7 +46,6 @@ function renderToPipe(rootElement, context, options) {
46
46
  shellChunkStatus = ShellChunkStatus.FINIESH;
47
47
  controller.enqueue(encodeForWebStream(`${shellBefore}${concatedChunk}${shellAfter}`));
48
48
  }
49
- controller.enqueue(encodeForWebStream(concatedChunk));
50
49
  } else {
51
50
  controller.enqueue(value);
52
51
  }
@@ -57,7 +56,7 @@ function renderToPipe(rootElement, context, options) {
57
56
  });
58
57
  return injectableStream;
59
58
  } catch (err) {
60
- ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
59
+ ssrContext === null || ssrContext === void 0 ? void 0 : ssrContext.metrics.emitCounter("app.render.streaming.shell.error", 1);
61
60
  const { shellAfter: shellAfter2, shellBefore: shellBefore2 } = getTemplates(context, RenderLevel.CLIENT_RENDER);
62
61
  const fallbackHtml = `${shellBefore2}${shellAfter2}`;
63
62
  return fallbackHtml;
@@ -100,7 +100,8 @@ class Entry {
100
100
  result: this.result,
101
101
  entryName: this.entryName,
102
102
  config: this.pluginConfig,
103
- nonce: this.nonce
103
+ nonce: this.nonce,
104
+ template: this.template
104
105
  };
105
106
  html = reduce(App, renderContext, [
106
107
  styledComponentRenderer.toHtml,
@@ -139,6 +140,7 @@ class Entry {
139
140
  _define_property(this, "result", void 0);
140
141
  _define_property(this, "metrics", void 0);
141
142
  _define_property(this, "logger", void 0);
143
+ _define_property(this, "template", void 0);
142
144
  _define_property(this, "App", void 0);
143
145
  _define_property(this, "fragments", void 0);
144
146
  _define_property(this, "pluginConfig", void 0);
@@ -147,6 +149,7 @@ class Entry {
147
149
  const { ctx, config } = options;
148
150
  const { entryName, template, request: { host }, nonce } = ctx;
149
151
  this.fragments = toFragments(template, entryName);
152
+ this.template = template;
150
153
  this.entryName = entryName;
151
154
  this.host = host;
152
155
  this.App = options.App;
@@ -37,9 +37,12 @@ export const toHtml = (jsx, renderer, next) => {
37
37
  default:
38
38
  }
39
39
  if (fileType === "js") {
40
- attributes.nonce = nonce;
41
- const attrsStr = attributesToString(attributes);
42
- chunksMap[fileType] += `<script${attrsStr} src="${v.url}"></script>`;
40
+ const jsChunkReg = new RegExp(`<script .*src="${v.url}".*>`);
41
+ if (!jsChunkReg.test(renderer.template)) {
42
+ attributes.nonce = nonce;
43
+ const attrsStr = attributesToString(attributes);
44
+ chunksMap[fileType] += `<script${attrsStr} src="${v.url}"></script>`;
45
+ }
43
46
  } else if (fileType === "css") {
44
47
  const attrsStr = attributesToString(attributes);
45
48
  chunksMap[fileType] += `<link${attrsStr} href="${v.url}" rel="stylesheet" />`;
@@ -13,6 +13,14 @@ export interface BaseRuntimeContext {
13
13
  store?: Store;
14
14
  routeManifest: RouteManifest;
15
15
  routerContext?: StaticHandlerContext;
16
+ /**
17
+ * private method
18
+ */
19
+ remixRouter?: Router;
20
+ /**
21
+ * private
22
+ */
23
+ unstable_getBlockNavState?: () => boolean;
16
24
  }
17
25
  export interface RuntimeContext extends BaseRuntimeContext {
18
26
  [key: string]: any;
@@ -10,6 +10,7 @@ export default class Entry {
10
10
  result: RenderResult;
11
11
  metrics: SSRServerContext['metrics'];
12
12
  logger: SSRServerContext['logger'];
13
+ private readonly template;
13
14
  private readonly App;
14
15
  private readonly fragments;
15
16
  private readonly pluginConfig;
@@ -19,6 +19,7 @@ export interface RenderEntry {
19
19
  result: RenderResult;
20
20
  stats: Record<string, any>;
21
21
  config: SSRPluginConfig;
22
+ template: string;
22
23
  nonce?: string;
23
24
  }
24
25
  export type RenderHandler = (jsx: React.ReactElement, renderer: RenderEntry, next: (jsx: React.ReactElement) => string) => string;
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.25.1",
18
+ "version": "2.26.0",
19
19
  "engines": {
20
20
  "node": ">=14.17.6"
21
21
  },
@@ -145,9 +145,9 @@
145
145
  "@babel/core": "^7.21.8",
146
146
  "@babel/types": "^7.21.5",
147
147
  "cookie": "0.5.0",
148
- "@loadable/babel-plugin": "^5.13.2",
149
- "@loadable/component": "^5.15.0",
150
- "@loadable/server": "^5.15.1",
148
+ "@loadable/babel-plugin": "5.15.3",
149
+ "@loadable/component": "5.15.3",
150
+ "@loadable/server": "5.15.3",
151
151
  "@loadable/webpack-plugin": "5.15.2",
152
152
  "@modern-js-reduck/plugin-auto-actions": "^1.1.10",
153
153
  "@modern-js-reduck/plugin-devtools": "^1.1.10",
@@ -169,9 +169,9 @@
169
169
  "redux-logger": "^3.0.6",
170
170
  "styled-components": "^5.3.1",
171
171
  "@swc/helpers": "0.5.1",
172
- "@modern-js/plugin": "2.25.1",
173
- "@modern-js/types": "2.25.1",
174
- "@modern-js/utils": "2.25.1"
172
+ "@modern-js/plugin": "2.26.0",
173
+ "@modern-js/types": "2.26.0",
174
+ "@modern-js/utils": "2.26.0"
175
175
  },
176
176
  "peerDependencies": {
177
177
  "react": ">=17",
@@ -191,12 +191,12 @@
191
191
  "react-dom": "^18",
192
192
  "ts-jest": "^29.1.0",
193
193
  "typescript": "^5",
194
- "webpack": "^5.82.1",
195
- "@modern-js/app-tools": "2.25.1",
196
- "@modern-js/core": "2.25.1",
197
- "@modern-js/server-core": "2.25.1",
198
- "@scripts/jest-config": "2.25.1",
199
- "@scripts/build": "2.25.1"
194
+ "webpack": "^5.88.1",
195
+ "@modern-js/app-tools": "2.26.0",
196
+ "@modern-js/core": "2.26.0",
197
+ "@modern-js/server-core": "2.26.0",
198
+ "@scripts/build": "2.26.0",
199
+ "@scripts/jest-config": "2.26.0"
200
200
  },
201
201
  "sideEffects": false,
202
202
  "modernConfig": {},
package/types/model.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- /// <reference types="@modern-js-reduck/plugin-auto-actions" />
2
- /// <reference types="@modern-js-reduck/plugin-devtools" />
3
- /// <reference types="@modern-js-reduck/plugin-effects" />
4
- /// <reference types="@modern-js-reduck/plugin-immutable" />
1
+ import '@modern-js-reduck/plugin-auto-actions';
2
+ import '@modern-js-reduck/plugin-devtools';
3
+ import '@modern-js-reduck/plugin-effects';
4
+ import '@modern-js-reduck/plugin-immutable';
5
5
 
6
6
  export { default } from '../dist/types/state';
7
7
  export * from '../dist/types/state';