@modern-js/runtime 2.6.0 → 2.8.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 (82) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +2 -2
  3. package/dist/cjs/cli/index.js +4 -3
  4. package/dist/cjs/common.js +6 -0
  5. package/dist/cjs/core/{app-config.js → appConfig.js} +3 -3
  6. package/dist/cjs/core/compatible.js +4 -4
  7. package/dist/cjs/core/index.js +6 -6
  8. package/dist/cjs/core/loader/useLoader.js +2 -2
  9. package/dist/cjs/core/types.js +15 -0
  10. package/dist/cjs/router/runtime/DeferredDataScripts.js +165 -0
  11. package/dist/cjs/router/runtime/index.js +116 -3
  12. package/dist/cjs/router/runtime/plugin.js +14 -1
  13. package/dist/cjs/router/runtime/plugin.node.js +12 -52
  14. package/dist/cjs/router/runtime/utils.js +68 -69
  15. package/dist/cjs/{runtime-context.js → runtimeContext.js} +3 -3
  16. package/dist/cjs/ssr/cli/index.js +3 -2
  17. package/dist/cjs/ssr/index.node.js +1 -0
  18. package/dist/cjs/ssr/serverRender/renderToStream/buildTemplate.after.js +2 -14
  19. package/dist/cjs/ssr/serverRender/renderToStream/bulidTemplate.before.js +5 -1
  20. package/dist/cjs/ssr/serverRender/renderToStream/renderToPipe.js +22 -7
  21. package/dist/cjs/ssr/serverRender/renderToStream/template.js +2 -1
  22. package/dist/cjs/ssr/serverRender/renderToString/entry.js +19 -8
  23. package/dist/cjs/state/runtime/index.js +2 -8
  24. package/dist/esm/cli/index.js +4 -3
  25. package/dist/esm/common.js +3 -1
  26. package/dist/esm/core/compatible.js +1 -1
  27. package/dist/esm/core/index.js +2 -2
  28. package/dist/esm/core/loader/useLoader.js +1 -1
  29. package/dist/esm/core/types.js +1 -0
  30. package/dist/esm/router/runtime/DeferredDataScripts.js +166 -0
  31. package/dist/esm/router/runtime/index.js +3 -2
  32. package/dist/esm/router/runtime/plugin.js +11 -3
  33. package/dist/esm/router/runtime/plugin.node.js +11 -68
  34. package/dist/esm/router/runtime/utils.js +138 -81
  35. package/dist/esm/ssr/cli/index.js +4 -3
  36. package/dist/esm/ssr/index.node.js +1 -0
  37. package/dist/esm/ssr/serverRender/renderToStream/buildTemplate.after.js +2 -4
  38. package/dist/esm/ssr/serverRender/renderToStream/bulidTemplate.before.js +1 -1
  39. package/dist/esm/ssr/serverRender/renderToStream/renderToPipe.js +19 -8
  40. package/dist/esm/ssr/serverRender/renderToStream/template.js +2 -1
  41. package/dist/esm/ssr/serverRender/renderToString/entry.js +15 -7
  42. package/dist/esm/state/runtime/index.js +1 -2
  43. package/dist/esm-node/cli/index.js +4 -3
  44. package/dist/esm-node/common.js +4 -0
  45. package/dist/esm-node/core/compatible.js +1 -1
  46. package/dist/esm-node/core/index.js +2 -2
  47. package/dist/esm-node/core/loader/useLoader.js +1 -1
  48. package/dist/esm-node/core/types.js +0 -0
  49. package/dist/esm-node/router/runtime/DeferredDataScripts.js +148 -0
  50. package/dist/esm-node/router/runtime/index.js +113 -2
  51. package/dist/esm-node/router/runtime/plugin.js +15 -2
  52. package/dist/esm-node/router/runtime/plugin.node.js +12 -55
  53. package/dist/esm-node/router/runtime/utils.js +59 -69
  54. package/dist/esm-node/ssr/cli/index.js +4 -3
  55. package/dist/esm-node/ssr/index.node.js +1 -0
  56. package/dist/esm-node/ssr/serverRender/renderToStream/buildTemplate.after.js +2 -4
  57. package/dist/esm-node/ssr/serverRender/renderToStream/bulidTemplate.before.js +5 -1
  58. package/dist/esm-node/ssr/serverRender/renderToStream/renderToPipe.js +22 -7
  59. package/dist/esm-node/ssr/serverRender/renderToStream/template.js +2 -1
  60. package/dist/esm-node/ssr/serverRender/renderToString/entry.js +19 -8
  61. package/dist/esm-node/state/runtime/index.js +1 -4
  62. package/dist/types/common.d.ts +3 -1
  63. package/dist/types/core/compatible.d.ts +1 -1
  64. package/dist/types/core/index.d.ts +4 -3
  65. package/dist/types/core/loader/index.d.ts +1 -2
  66. package/dist/types/core/loader/useLoader.d.ts +1 -15
  67. package/dist/types/core/plugin.d.ts +15 -15
  68. package/dist/types/core/types.d.ts +22 -0
  69. package/dist/types/index.d.ts +1 -1
  70. package/dist/types/router/runtime/DeferredDataScripts.d.ts +8 -0
  71. package/dist/types/router/runtime/index.d.ts +4 -2
  72. package/dist/types/router/runtime/utils.d.ts +23 -4
  73. package/dist/types/{runtime-context.d.ts → runtimeContext.d.ts} +2 -0
  74. package/dist/types/ssr/serverRender/renderToStream/buildTemplate.after.d.ts +2 -0
  75. package/dist/types/state/runtime/index.d.ts +0 -1
  76. package/package.json +15 -18
  77. package/types/router.d.ts +1 -1
  78. /package/dist/esm/core/{app-config.js → appConfig.js} +0 -0
  79. /package/dist/esm/{runtime-context.js → runtimeContext.js} +0 -0
  80. /package/dist/esm-node/core/{app-config.js → appConfig.js} +0 -0
  81. /package/dist/esm-node/{runtime-context.js → runtimeContext.js} +0 -0
  82. /package/dist/types/core/{app-config.d.ts → appConfig.d.ts} +0 -0
@@ -1,54 +1,16 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { Suspense } from "react";
3
2
  import { Route } from "react-router-dom";
3
+ import { renderNestedRoute } from "@modern-js/utils/nestedRoutes";
4
+ import {
5
+ ErrorResponse,
6
+ isRouteErrorResponse
7
+ } from "@modern-js/utils/remix-router";
4
8
  import { DefaultNotFound } from "./DefaultNotFound";
5
- const renderNestedRoute = (nestedRoute, parent) => {
6
- const { children, index, id, component, isRoot } = nestedRoute;
7
- const Component = component;
8
- const routeProps = {
9
- caseSensitive: nestedRoute.caseSensitive,
10
- path: nestedRoute.path,
11
- id: nestedRoute.id,
12
- loader: createLoader(nestedRoute),
13
- action: nestedRoute.action,
14
- hasErrorBoundary: nestedRoute.hasErrorBoundary,
15
- shouldRevalidate: nestedRoute.shouldRevalidate,
16
- handle: nestedRoute.handle,
17
- index: nestedRoute.index,
18
- element: nestedRoute.element,
19
- errorElement: nestedRoute.errorElement
20
- };
21
- if (nestedRoute.error) {
22
- const errorElement = /* @__PURE__ */ jsx(nestedRoute.error, {});
23
- routeProps.errorElement = errorElement;
24
- }
25
- let element;
26
- if (Component) {
27
- if (parent == null ? void 0 : parent.loading) {
28
- const Loading = parent.loading;
29
- if (isLoadableComponent(Component)) {
30
- element = /* @__PURE__ */ jsx(Component, { fallback: /* @__PURE__ */ jsx(Loading, {}) });
31
- } else {
32
- element = /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Loading, {}), children: /* @__PURE__ */ jsx(Component, {}) });
33
- }
34
- } else if (isLoadableComponent(Component) || isRoot) {
35
- element = /* @__PURE__ */ jsx(Component, {});
36
- } else {
37
- element = /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(Component, {}) });
38
- }
39
- } else {
40
- nestedRoute.loading = parent == null ? void 0 : parent.loading;
41
- }
42
- if (element) {
43
- routeProps.element = element;
44
- }
45
- const childElements = children == null ? void 0 : children.map((childRoute) => {
46
- return renderNestedRoute(childRoute, nestedRoute);
47
- });
48
- const routeElement = index ? /* @__PURE__ */ jsx(Route, { ...routeProps, index: true }, id) : /* @__PURE__ */ jsx(Route, { ...routeProps, index: false, children: childElements }, id);
49
- return routeElement;
50
- };
51
- function getRouteComponents(routes, globalApp) {
9
+ import DeferredDataScripts from "./DeferredDataScripts";
10
+ function getRouteComponents(routes, {
11
+ globalApp,
12
+ ssrMode
13
+ }) {
52
14
  const Layout = ({ Component, ...props }) => {
53
15
  const GlobalLayout = globalApp;
54
16
  if (!GlobalLayout) {
@@ -59,7 +21,9 @@ function getRouteComponents(routes, globalApp) {
59
21
  const routeElements = [];
60
22
  for (const route of routes) {
61
23
  if (route.type === "nested") {
62
- const routeElement = renderNestedRoute(route);
24
+ const routeElement = renderNestedRoute(route, {
25
+ DeferredDataComponent: ssrMode === "stream" ? DeferredDataScripts : void 0
26
+ });
63
27
  routeElements.push(routeElement);
64
28
  } else {
65
29
  const routeElement = /* @__PURE__ */ jsx(
@@ -76,7 +40,7 @@ function getRouteComponents(routes, globalApp) {
76
40
  routeElements.push(/* @__PURE__ */ jsx(Route, { path: "*", element: /* @__PURE__ */ jsx(DefaultNotFound, {}) }, "*"));
77
41
  return routeElements;
78
42
  }
79
- function renderRoutes(routesConfig) {
43
+ function renderRoutes(routesConfig, ssrMode) {
80
44
  if (!routesConfig) {
81
45
  return null;
82
46
  }
@@ -84,7 +48,7 @@ function renderRoutes(routesConfig) {
84
48
  if (!routes) {
85
49
  return null;
86
50
  }
87
- const routeElements = getRouteComponents(routes, globalApp);
51
+ const routeElements = getRouteComponents(routes, { globalApp, ssrMode });
88
52
  return routeElements;
89
53
  }
90
54
  function getLocation(serverContext) {
@@ -118,31 +82,57 @@ function standardSlash(str) {
118
82
  }
119
83
  return addr;
120
84
  }
121
- function createLoader(route) {
122
- const { loader } = route;
123
- if (loader) {
124
- return (args) => {
125
- if (typeof route.lazyImport === "function") {
126
- route.lazyImport();
127
- }
128
- return loader(args);
129
- };
130
- } else {
131
- return () => {
132
- if (typeof route.lazyImport === "function") {
133
- route.lazyImport();
134
- }
135
- return null;
136
- };
85
+ function serializeErrors(errors) {
86
+ if (!errors) {
87
+ return null;
137
88
  }
89
+ const entries = Object.entries(errors);
90
+ const serialized = {};
91
+ for (const [key, val] of entries) {
92
+ if (isRouteErrorResponse(val)) {
93
+ serialized[key] = { ...val, __type: "RouteErrorResponse" };
94
+ } else if (val instanceof Error) {
95
+ serialized[key] = {
96
+ message: val.message,
97
+ stack: val.stack,
98
+ __type: "Error"
99
+ };
100
+ } else {
101
+ serialized[key] = val;
102
+ }
103
+ }
104
+ return serialized;
138
105
  }
139
- function isLoadableComponent(component) {
140
- return component && component.displayName === "Loadable" && component.preload && typeof component.preload === "function";
106
+ function deserializeErrors(errors) {
107
+ if (!errors) {
108
+ return null;
109
+ }
110
+ const entries = Object.entries(errors);
111
+ const serialized = {};
112
+ for (const [key, val] of entries) {
113
+ if (val && val.__type === "RouteErrorResponse") {
114
+ serialized[key] = new ErrorResponse(
115
+ val.status,
116
+ val.statusText,
117
+ val.data,
118
+ val.internal === true
119
+ );
120
+ } else if (val && val.__type === "Error") {
121
+ const error = new Error(val.message);
122
+ error.stack = val.stack;
123
+ serialized[key] = error;
124
+ } else {
125
+ serialized[key] = val;
126
+ }
127
+ }
128
+ return serialized;
141
129
  }
142
130
  export {
131
+ deserializeErrors,
143
132
  getLocation,
144
133
  getRouteComponents,
145
134
  renderRoutes,
135
+ serializeErrors,
146
136
  standardSlash,
147
137
  urlJoin
148
138
  };
@@ -5,7 +5,7 @@ import {
5
5
  LOADABLE_STATS_FILE,
6
6
  isUseSSRBundle,
7
7
  createRuntimeExportsUtils,
8
- isSingleEntry
8
+ isSSGEntry
9
9
  } from "@modern-js/utils";
10
10
  const PLUGIN_IDENTIFIER = "ssr";
11
11
  const hasStringSSREntry = (userConfig) => {
@@ -39,6 +39,8 @@ var cli_default = () => ({
39
39
  return {
40
40
  source: {
41
41
  alias: {
42
+ // ensure that all packages use the same storage in @modern-js/utils/ssr
43
+ "@modern-js/utils/ssr": require.resolve("@modern-js/utils/ssr"),
42
44
  "@modern-js/runtime/plugins": pluginsExportsUtils.getPath()
43
45
  }
44
46
  },
@@ -111,8 +113,7 @@ var cli_default = () => ({
111
113
  );
112
114
  }
113
115
  }
114
- const ssgConfig = userConfig.output.ssg;
115
- const useSSG = isSingleEntry(entrypoints) ? Boolean(ssgConfig) : ssgConfig === true || typeof (ssgConfig == null ? void 0 : ssgConfig[0]) === "function" || Boolean(ssgConfig == null ? void 0 : ssgConfig[entryName]);
116
+ const useSSG = isSSGEntry(userConfig, entryName, entrypoints);
116
117
  ssrConfigMap.set(entryName, ssrConfig || useSSG);
117
118
  if (ssrConfig || useSSG) {
118
119
  imports.push({
@@ -15,6 +15,7 @@ const ssr = (config = {}) => ({
15
15
  init({ context }, next) {
16
16
  const { request } = context.ssrContext;
17
17
  context.ssrContext.request = formatServer(request);
18
+ context.ssrContext.mode = config.mode;
18
19
  return next({ context });
19
20
  },
20
21
  pickContext: ({ context, pickedContext }, next) => {
@@ -1,4 +1,4 @@
1
- import serialize from "serialize-javascript";
1
+ import { serializeJson } from "@modern-js/utils/serialize";
2
2
  import { buildTemplate } from "./buildTemplate.share";
3
3
  function buildShellAfterTemplate(afterAppTemplate, options) {
4
4
  const callbacks = [injectSSRDataScript];
@@ -26,9 +26,7 @@ function buildShellAfterTemplate(afterAppTemplate, options) {
26
26
  renderLevel
27
27
  };
28
28
  return `
29
- <script>window._SSR_DATA = ${serialize(SSRData, {
30
- isJSON: true
31
- })}</script>
29
+ <script>window._SSR_DATA = ${serializeJson(SSRData)}</script>
32
30
  `;
33
31
  }
34
32
  }
@@ -29,7 +29,11 @@ function getHeadTemplate(beforeEntryTemplate, context) {
29
29
  }
30
30
  const { routeAssets } = routeManifest;
31
31
  const cssChunks = [];
32
- const matches = matchRoutes(routes, routerContext.location);
32
+ const matches = matchRoutes(
33
+ routes,
34
+ routerContext.location,
35
+ routerContext.basename
36
+ );
33
37
  matches == null ? void 0 : matches.forEach((match, index) => {
34
38
  if (!index) {
35
39
  return;
@@ -1,8 +1,15 @@
1
1
  import { Transform } from "stream";
2
2
  import { RenderLevel } from "../types";
3
+ import { ESCAPED_SHELL_STREAM_END_MARK } from "../../../common";
3
4
  import { getTemplates } from "./template";
5
+ var ShellChunkStatus = /* @__PURE__ */ ((ShellChunkStatus2) => {
6
+ ShellChunkStatus2[ShellChunkStatus2["IDLE"] = 0] = "IDLE";
7
+ ShellChunkStatus2[ShellChunkStatus2["START"] = 1] = "START";
8
+ ShellChunkStatus2[ShellChunkStatus2["FINIESH"] = 2] = "FINIESH";
9
+ return ShellChunkStatus2;
10
+ })(ShellChunkStatus || {});
4
11
  function renderToPipe(rootElement, context, options) {
5
- let isShellStream = true;
12
+ let shellChunkStatus = 0 /* IDLE */;
6
13
  const { ssrContext } = context;
7
14
  const forUserPipe = (stream) => {
8
15
  return new Promise((resolve) => {
@@ -23,9 +30,20 @@ function renderToPipe(rootElement, context, options) {
23
30
  const injectableTransform = new Transform({
24
31
  transform(chunk, _encoding, callback) {
25
32
  try {
26
- if (isShellStream) {
27
- this.push(joinChunk(shellBefore, chunk, shellAfter));
28
- isShellStream = false;
33
+ if (shellChunkStatus !== 2 /* FINIESH */) {
34
+ let concatedChunk = chunk.toString();
35
+ if (shellChunkStatus === 0 /* IDLE */) {
36
+ concatedChunk = `${shellBefore}${concatedChunk}`;
37
+ shellChunkStatus = 1 /* START */;
38
+ }
39
+ if (shellChunkStatus === 1 /* START */ && concatedChunk.endsWith(ESCAPED_SHELL_STREAM_END_MARK)) {
40
+ concatedChunk = concatedChunk.replace(
41
+ ESCAPED_SHELL_STREAM_END_MARK,
42
+ shellAfter
43
+ );
44
+ shellChunkStatus = 2 /* FINIESH */;
45
+ }
46
+ this.push(concatedChunk);
29
47
  } else {
30
48
  this.push(chunk);
31
49
  }
@@ -68,9 +86,6 @@ function renderToPipe(rootElement, context, options) {
68
86
  });
69
87
  };
70
88
  return forUserPipe;
71
- function joinChunk(before = "", chunk, after = "") {
72
- return `${before}${chunk.toString()}${after}`;
73
- }
74
89
  }
75
90
  var renderToPipe_default = renderToPipe;
76
91
  export {
@@ -2,7 +2,7 @@ import { buildShellAfterTemplate } from "./buildTemplate.after";
2
2
  import { buildShellBeforeTemplate } from "./bulidTemplate.before";
3
3
  const HTML_SEPARATOR = "<!--<?- html ?>-->";
4
4
  const getTemplates = (context, renderLevel) => {
5
- const { ssrContext } = context;
5
+ const { ssrContext, routerContext } = context;
6
6
  const [beforeAppTemplate = "", afterAppHtmlTemplate = ""] = ssrContext.template.split(HTML_SEPARATOR) || [];
7
7
  const builtBeforeTemplate = buildShellBeforeTemplate(
8
8
  beforeAppTemplate,
@@ -10,6 +10,7 @@ const getTemplates = (context, renderLevel) => {
10
10
  );
11
11
  const builtAfterTemplate = buildShellAfterTemplate(afterAppHtmlTemplate, {
12
12
  ssrContext,
13
+ routerContext,
13
14
  renderLevel
14
15
  });
15
16
  return {
@@ -1,7 +1,8 @@
1
1
  import React from "react";
2
2
  import ReactDomServer from "react-dom/server";
3
- import serialize from "serialize-javascript";
3
+ import { serializeJson } from "@modern-js/utils/serialize";
4
4
  import ReactHelmet from "react-helmet";
5
+ import { serializeErrors } from "../../../router/runtime/utils";
5
6
  import helmetReplace from "../helmet";
6
7
  import {
7
8
  RenderLevel
@@ -72,13 +73,18 @@ class Entry {
72
73
  if ((_c = ssrContext.redirection) == null ? void 0 : _c.url) {
73
74
  return "";
74
75
  }
76
+ const { routerContext } = context;
77
+ const routerData = routerContext ? {
78
+ loaderData: routerContext.loaderData,
79
+ errors: serializeErrors(routerContext.errors)
80
+ } : void 0;
75
81
  let html = "";
76
82
  const templateData = buildTemplateData(
77
83
  ssrContext,
78
84
  prefetchData,
79
85
  this.result.renderLevel
80
86
  );
81
- const SSRData = this.getSSRDataScript(templateData);
87
+ const SSRData = this.getSSRDataScript(templateData, routerData);
82
88
  for (const fragment of this.fragments) {
83
89
  if (fragment.isVariable && fragment.content === "SSRDataScript") {
84
90
  html += fragment.getValue(SSRData);
@@ -135,13 +141,18 @@ class Entry {
135
141
  }
136
142
  return html;
137
143
  }
138
- getSSRDataScript(templateData) {
144
+ getSSRDataScript(templateData, routerData) {
145
+ let ssrDataScripts = `<script>window._SSR_DATA = ${serializeJson(
146
+ templateData
147
+ )}</script>`;
148
+ if (routerData) {
149
+ ssrDataScripts += `
150
+ <script>window._ROUTER_DATA = ${serializeJson(
151
+ routerData
152
+ )}</script>`;
153
+ }
139
154
  return {
140
- SSRDataScript: `
141
- <script>window._SSR_DATA = ${serialize(templateData, {
142
- isJSON: true
143
- })}</script>
144
- `
155
+ SSRDataScript: ssrDataScripts
145
156
  };
146
157
  }
147
158
  }
@@ -1,9 +1,6 @@
1
1
  export * from "@modern-js-reduck/react";
2
- import { model, createStore } from "@modern-js-reduck/store";
3
2
  import { default as default2 } from "./plugin";
4
3
  export * from "./plugin";
5
4
  export {
6
- createStore,
7
- default2 as default,
8
- model
5
+ default2 as default
9
6
  };
@@ -3,4 +3,6 @@ export declare const isBrowser: () => boolean;
3
3
  export interface AppConfig {
4
4
  state?: StateConfig | boolean;
5
5
  [key: string]: any;
6
- }
6
+ }
7
+ export declare const JSX_SHELL_STREAM_END_MARK = "<!--<?- SHELL_STREAM_END ?>-->";
8
+ export declare const ESCAPED_SHELL_STREAM_END_MARK = "&lt;!--&lt;?- SHELL_STREAM_END ?&gt;--&gt;";
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Renderer } from 'react-dom';
3
3
  import type { hydrateRoot, createRoot } from 'react-dom/client';
4
- import { RuntimeContext, TRuntimeContext } from '../runtime-context';
4
+ import { RuntimeContext, TRuntimeContext } from '../runtimeContext';
5
5
  import { Plugin } from './plugin';
6
6
  export type CreateAppOptions = {
7
7
  plugins: Plugin[];
@@ -1,8 +1,9 @@
1
1
  export { createPlugin, createRuntime, runtime, registerInit } from './plugin';
2
2
  export type { Plugin } from './plugin';
3
- export { defineConfig, getConfig } from './app-config';
3
+ export { defineConfig, getConfig } from './appConfig';
4
4
  export * from './compatible';
5
- export type { TRuntimeContext, RuntimeContext } from '../runtime-context';
6
- export { RuntimeReactContext, ServerRouterContext } from '../runtime-context';
5
+ export type { TRuntimeContext, RuntimeContext } from '../runtimeContext';
6
+ export { RuntimeReactContext, ServerRouterContext } from '../runtimeContext';
7
7
  export * from './loader';
8
+ export type { SSRData, SSRContainer } from './types';
8
9
  export * from '@modern-js/plugin';
@@ -1,2 +1 @@
1
- export { default as useLoader } from './useLoader';
2
- export type { SSRData, SSRContainer } from './useLoader';
1
+ export { default as useLoader } from './useLoader';
@@ -1,17 +1,4 @@
1
- import { LoaderResult } from './loaderManager';
2
- export interface SSRData {
3
- loadersData: Record<string, LoaderResult | undefined>;
4
- initialData?: Record<string, unknown>;
5
- storeState?: any;
6
- }
7
- export interface SSRContainer {
8
- data?: SSRData;
9
- }
10
- declare global {
11
- interface Window {
12
- _SSR_DATA?: SSRContainer;
13
- }
14
- }
1
+ type LoaderFn<P = any, T = any> = (context: any, params: P) => Promise<T>;
15
2
  export interface LoaderOptions<Params = any, TData = any, TError extends Error = any> {
16
3
  /**
17
4
  * Revoke when loader excuted successfully.
@@ -44,7 +31,6 @@ export interface LoaderOptions<Params = any, TData = any, TError extends Error =
44
31
 
45
32
  static?: boolean;
46
33
  }
47
- type LoaderFn<P = any, T = any> = (context: any, params: P) => Promise<T>;
48
34
  declare const useLoader: <TData = any, Params = any, E = any>(loaderFn: LoaderFn<Params, TData>, options?: LoaderOptions<Params, any, any>) => {
49
35
  reload: (params?: Params | undefined) => Promise<any> | undefined;
50
36
  loading: boolean;
@@ -1,6 +1,6 @@
1
1
  import type React from 'react';
2
2
  import { Setup, ToThreads, CommonAPI, PluginOptions } from '@modern-js/plugin';
3
- import type { RuntimeContext, TRuntimeContext } from '../runtime-context';
3
+ import type { RuntimeContext, TRuntimeContext } from '../runtimeContext';
4
4
  export interface AppProps {}
5
5
  declare const runtimeHooks: {
6
6
  hoc: import("@modern-js/plugin").Pipeline<{
@@ -13,13 +13,13 @@ declare const runtimeHooks: {
13
13
  }, JSX.Element>;
14
14
  client: import("@modern-js/plugin").AsyncPipeline<{
15
15
  App: React.ComponentType<any>;
16
- readonly context?: RuntimeContext | undefined;
16
+ readonly context: RuntimeContext;
17
17
  ModernRender: (App: React.ReactElement) => void;
18
18
  ModernHydrate: (App: React.ReactElement, callback?: () => void) => void;
19
19
  }, void>;
20
20
  server: import("@modern-js/plugin").AsyncPipeline<{
21
21
  App: React.ComponentType<any>;
22
- readonly context?: RuntimeContext | undefined;
22
+ readonly context: RuntimeContext;
23
23
  }, string>;
24
24
  init: import("@modern-js/plugin").AsyncPipeline<{
25
25
  context: RuntimeContext;
@@ -52,13 +52,13 @@ export declare const createRuntime: () => import("@modern-js/plugin").Manager<{
52
52
  }, JSX.Element>;
53
53
  client: import("@modern-js/plugin").AsyncPipeline<{
54
54
  App: React.ComponentType<any>;
55
- readonly context?: RuntimeContext | undefined;
55
+ readonly context: RuntimeContext;
56
56
  ModernRender: (App: React.ReactElement) => void;
57
57
  ModernHydrate: (App: React.ReactElement, callback?: () => void) => void;
58
58
  }, void>;
59
59
  server: import("@modern-js/plugin").AsyncPipeline<{
60
60
  App: React.ComponentType<any>;
61
- readonly context?: RuntimeContext | undefined;
61
+ readonly context: RuntimeContext;
62
62
  }, string>;
63
63
  init: import("@modern-js/plugin").AsyncPipeline<{
64
64
  context: RuntimeContext;
@@ -84,13 +84,13 @@ export declare const runtime: import("@modern-js/plugin").Manager<{
84
84
  }, JSX.Element>;
85
85
  client: import("@modern-js/plugin").AsyncPipeline<{
86
86
  App: React.ComponentType<any>;
87
- readonly context?: RuntimeContext | undefined;
87
+ readonly context: RuntimeContext;
88
88
  ModernRender: (App: React.ReactElement) => void;
89
89
  ModernHydrate: (App: React.ReactElement, callback?: () => void) => void;
90
90
  }, void>;
91
91
  server: import("@modern-js/plugin").AsyncPipeline<{
92
92
  App: React.ComponentType<any>;
93
- readonly context?: RuntimeContext | undefined;
93
+ readonly context: RuntimeContext;
94
94
  }, string>;
95
95
  init: import("@modern-js/plugin").AsyncPipeline<{
96
96
  context: RuntimeContext;
@@ -111,13 +111,13 @@ export declare const createPlugin: (setup?: Setup<{
111
111
  }, JSX.Element>;
112
112
  client: import("@modern-js/plugin").AsyncPipeline<{
113
113
  App: React.ComponentType<any>;
114
- readonly context?: RuntimeContext | undefined;
114
+ readonly context: RuntimeContext;
115
115
  ModernRender: (App: React.ReactElement) => void;
116
116
  ModernHydrate: (App: React.ReactElement, callback?: () => void) => void;
117
117
  }, void>;
118
118
  server: import("@modern-js/plugin").AsyncPipeline<{
119
119
  App: React.ComponentType<any>;
120
- readonly context?: RuntimeContext | undefined;
120
+ readonly context: RuntimeContext;
121
121
  }, string>;
122
122
  init: import("@modern-js/plugin").AsyncPipeline<{
123
123
  context: RuntimeContext;
@@ -137,13 +137,13 @@ export declare const createPlugin: (setup?: Setup<{
137
137
  }, JSX.Element>;
138
138
  client: import("@modern-js/plugin").AsyncPipeline<{
139
139
  App: React.ComponentType<any>;
140
- readonly context?: RuntimeContext | undefined;
140
+ readonly context: RuntimeContext;
141
141
  ModernRender: (App: React.ReactElement) => void;
142
142
  ModernHydrate: (App: React.ReactElement, callback?: () => void) => void;
143
143
  }, void>;
144
144
  server: import("@modern-js/plugin").AsyncPipeline<{
145
145
  App: React.ComponentType<any>;
146
- readonly context?: RuntimeContext | undefined;
146
+ readonly context: RuntimeContext;
147
147
  }, string>;
148
148
  init: import("@modern-js/plugin").AsyncPipeline<{
149
149
  context: RuntimeContext;
@@ -163,13 +163,13 @@ export declare const createPlugin: (setup?: Setup<{
163
163
  }, JSX.Element>;
164
164
  client: import("@modern-js/plugin").AsyncPipeline<{
165
165
  App: React.ComponentType<any>;
166
- readonly context?: RuntimeContext | undefined;
166
+ readonly context: RuntimeContext;
167
167
  ModernRender: (App: React.ReactElement) => void;
168
168
  ModernHydrate: (App: React.ReactElement, callback?: () => void) => void;
169
169
  }, void>;
170
170
  server: import("@modern-js/plugin").AsyncPipeline<{
171
171
  App: React.ComponentType<any>;
172
- readonly context?: RuntimeContext | undefined;
172
+ readonly context: RuntimeContext;
173
173
  }, string>;
174
174
  init: import("@modern-js/plugin").AsyncPipeline<{
175
175
  context: RuntimeContext;
@@ -189,13 +189,13 @@ export declare const createPlugin: (setup?: Setup<{
189
189
  }, JSX.Element>;
190
190
  client: import("@modern-js/plugin").AsyncPipeline<{
191
191
  App: React.ComponentType<any>;
192
- readonly context?: RuntimeContext | undefined;
192
+ readonly context: RuntimeContext;
193
193
  ModernRender: (App: React.ReactElement) => void;
194
194
  ModernHydrate: (App: React.ReactElement, callback?: () => void) => void;
195
195
  }, void>;
196
196
  server: import("@modern-js/plugin").AsyncPipeline<{
197
197
  App: React.ComponentType<any>;
198
- readonly context?: RuntimeContext | undefined;
198
+ readonly context: RuntimeContext;
199
199
  }, string>;
200
200
  init: import("@modern-js/plugin").AsyncPipeline<{
201
201
  context: RuntimeContext;
@@ -0,0 +1,22 @@
1
+ import type { LoaderResult } from './loader/loaderManager';
2
+ declare global {
3
+ interface Window {
4
+ _SSR_DATA?: SSRContainer;
5
+ _ROUTER_DATA?: RouterSSRData;
6
+ }
7
+ }
8
+ export interface SSRData {
9
+ loadersData: Record<string, LoaderResult | undefined>;
10
+ initialData?: Record<string, unknown>;
11
+ storeState?: any;
12
+ }
13
+ export interface RouteData {
14
+ [routeId: string]: any;
15
+ }
16
+ export interface RouterSSRData {
17
+ loaderData: RouteData;
18
+ errors: RouteData | null;
19
+ }
20
+ export interface SSRContainer {
21
+ data?: SSRData;
22
+ }
@@ -3,7 +3,7 @@ import type { RouterConfig } from './router';
3
3
  export type { Plugin } from './core';
4
4
  export type { AppConfig } from './common';
5
5
  export { isBrowser } from './common';
6
- export type { BaseRuntimeContext, RuntimeContext, BaseTRuntimeContext, TRuntimeContext } from './runtime-context';
6
+ export type { BaseRuntimeContext, RuntimeContext, BaseTRuntimeContext, TRuntimeContext } from './runtimeContext';
7
7
  export type { RuntimeUserConfig } from './config';
8
8
  export { createApp, createPlugin, useLoader, bootstrap, RuntimeReactContext, defineConfig, registerInit, useRuntimeContext } from './core';
9
9
  export { StateConfig, RouterConfig };
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+
3
+ /**
4
+ * DeferredDataScripts only renders in server side,
5
+ * it doesn't need to be hydrated in client side.
6
+ */
7
+ declare const DeferredDataScripts: () => JSX.Element | null;
8
+ export default DeferredDataScripts;
@@ -3,5 +3,7 @@ import type { SingleRouteConfig, RouterConfig } from './types';
3
3
  export type { SingleRouteConfig, RouterConfig };
4
4
  export default routerPlugin;
5
5
  export { modifyRoutes } from './plugin';
6
- export * from 'react-router-dom';
7
- export * from './withRouter';
6
+ export * from './withRouter';
7
+ export type { FormEncType, FormMethod, GetScrollRestorationKeyFunction, ParamKeyValuePair, SubmitOptions, URLSearchParamsInit, FetcherWithComponents, ActionFunction, ActionFunctionArgs, AwaitProps, unstable_Blocker, unstable_BlockerFunction, DataRouteMatch, DataRouteObject, Fetcher, Hash, IndexRouteObject, IndexRouteProps, JsonFunction, LayoutRouteProps, LoaderFunction, LoaderFunctionArgs, Location, MemoryRouterProps, NavigateFunction, NavigateOptions, NavigateProps, Navigation, Navigator, NavLinkProps, NonIndexRouteObject, OutletProps, Params, ParamParseKey, Path, PathMatch, Pathname, PathPattern, PathRouteProps, RedirectFunction, RelativeRoutingType, RouteMatch, RouteObject, RouteProps, RouterProps, RouterProviderProps, RoutesProps, Search, ShouldRevalidateFunction, To } from 'react-router-dom';
8
+ export { createBrowserRouter, createHashRouter, createMemoryRouter, RouterProvider, BrowserRouter, HashRouter, MemoryRouter, Router, Await, Form, Link, NavLink, Navigate, Outlet, Route, Routes, ScrollRestoration, useActionData, useAsyncError, useAsyncValue, useBeforeUnload, useFetcher, useFetchers, useFormAction, useHref, useInRouterContext, useLinkClickHandler, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, useSearchParams, useSubmit, createRoutesFromChildren, createRoutesFromElements, createSearchParams, generatePath, isRouteErrorResponse, matchPath, matchRoutes, renderMatches, resolvePath } from 'react-router-dom';
9
+ export { defer, json, redirect } from '@modern-js/utils/remix-router';
@@ -1,8 +1,27 @@
1
1
  import React from 'react';
2
- import type { NestedRoute, PageRoute } from '@modern-js/types';
2
+ import { type NestedRoute, type PageRoute, type SSRMode } from '@modern-js/types';
3
+ import { type Router, type StaticHandlerContext } from '@modern-js/utils/remix-router';
3
4
  import { RouterConfig } from './types';
4
- export declare function getRouteComponents(routes: (NestedRoute | PageRoute)[], globalApp?: React.ComponentType<any>): React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
5
- export declare function renderRoutes(routesConfig: RouterConfig['routesConfig']): React.ReactElement<any, string | React.JSXElementConstructor<any>>[] | null;
5
+ export declare function getRouteComponents(routes: (NestedRoute | PageRoute)[], {
6
+ globalApp,
7
+ ssrMode
8
+ }: {
9
+ globalApp?: React.ComponentType<any>;
10
+ ssrMode?: SSRMode;
11
+ }): React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
12
+ export declare function renderRoutes(routesConfig: RouterConfig['routesConfig'], ssrMode?: SSRMode): React.ReactElement<any, string | React.JSXElementConstructor<any>>[] | null;
6
13
  export declare function getLocation(serverContext: any): string;
7
14
  export declare const urlJoin: (...parts: string[]) => string;
8
- export declare function standardSlash(str: string): string;
15
+ export declare function standardSlash(str: string): string;
16
+ /**
17
+ * forked from https://github.com/remix-run/remix/blob/main/packages/remix-server-runtime/errors.ts
18
+ * license at https://github.com/remix-run/remix/blob/main/LICENSE.md
19
+ */
20
+
21
+ export declare function serializeErrors(errors: StaticHandlerContext['errors']): StaticHandlerContext['errors'];
22
+ /**
23
+ * forked from https://github.com/remix-run/remix/blob/main/packages/remix-react/errors.ts
24
+ * license at https://github.com/remix-run/remix/blob/main/LICENSE.md
25
+ */
26
+
27
+ export declare function deserializeErrors(errors: Router['state']['errors']): Router['state']['errors'];
@@ -1,5 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { Store } from '@modern-js-reduck/store';
3
+ import type { StaticHandlerContext } from '@modern-js/utils/remix-router';
3
4
  import { createLoaderManager } from './core/loader/loaderManager';
4
5
  import { runtime } from './core/plugin';
5
6
  import { SSRServerContext } from './ssr/serverRender/types';
@@ -9,6 +10,7 @@ export interface BaseRuntimeContext {
9
10
  runner: ReturnType<typeof runtime.init>;
10
11
  ssrContext?: SSRServerContext;
11
12
  store?: Store;
13
+ routerContext?: StaticHandlerContext;
12
14
  }
13
15
  export interface RuntimeContext extends BaseRuntimeContext {
14
16
  [key: string]: any;