@shuvi/platform-web 1.0.0-rc.4 → 1.0.0-rc.7
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.
- package/esm/shared/appTypes.d.ts +4 -2
- package/esm/shared/renderTypes.d.ts +6 -5
- package/esm/shared/routeTypes.d.ts +4 -9
- package/esm/shuvi-app/app/client.js +11 -16
- package/esm/shuvi-app/app/server.js +10 -9
- package/esm/shuvi-app/dev/hotDevClient.d.ts +0 -1
- package/esm/shuvi-app/dev/hotDevClient.js +30 -51
- package/esm/shuvi-app/dev/websocket.d.ts +0 -1
- package/esm/shuvi-app/helper/serializeServerError.d.ts +2 -0
- package/esm/shuvi-app/helper/serializeServerError.js +21 -0
- package/esm/shuvi-app/react/AppContainer.d.ts +2 -3
- package/esm/shuvi-app/react/AppContainer.jsx +3 -4
- package/esm/shuvi-app/react/getRoutes.js +5 -3
- package/esm/shuvi-app/react/{redox-react → model}/RedoxWrapper.d.ts +3 -3
- package/esm/shuvi-app/react/{redox-react → model}/RedoxWrapper.jsx +3 -3
- package/esm/shuvi-app/react/model/runtime.d.ts +8 -0
- package/esm/shuvi-app/react/{redox-react → model}/runtime.js +6 -3
- package/esm/shuvi-app/react/store.d.ts +5 -0
- package/esm/shuvi-app/react/store.js +3 -0
- package/esm/shuvi-app/react/types.d.ts +0 -7
- package/esm/shuvi-app/react/useLoaderData.js +9 -20
- package/esm/shuvi-app/react/view/ReactView.client.jsx +25 -4
- package/esm/shuvi-app/react/view/ReactView.server.jsx +17 -14
- package/esm/shuvi-app/shuvi-runtime-index.d.ts +3 -3
- package/lib/node/features/custom-server/index.d.ts +1 -1
- package/lib/node/features/custom-server/server.d.ts +1 -1
- package/lib/node/features/filesystem-routes/api/apiRouteHandler.d.ts +7 -7
- package/lib/node/features/filesystem-routes/api/apiRouteHandler.js +0 -4
- package/lib/node/features/filesystem-routes/api/middleware.d.ts +2 -2
- package/lib/node/features/filesystem-routes/index.d.ts +1 -13
- package/lib/node/features/filesystem-routes/index.js +3 -41
- package/lib/node/features/filesystem-routes/middleware/middleware.d.ts +2 -2
- package/lib/node/features/filesystem-routes/page/routes.js +1 -1
- package/lib/node/features/html-render/index.js +1 -1
- package/lib/node/features/html-render/lib/getPageMiddleware.d.ts +2 -2
- package/lib/node/features/html-render/lib/index.d.ts +0 -1
- package/lib/node/features/html-render/lib/index.js +1 -3
- package/lib/node/features/html-render/lib/renderToHTML.d.ts +2 -2
- package/lib/node/features/html-render/lib/renderToHTML.js +7 -48
- package/lib/node/features/html-render/lib/renderer/base.d.ts +6 -6
- package/lib/node/features/html-render/lib/renderer/base.js +5 -5
- package/lib/node/features/html-render/lib/renderer/index.d.ts +5 -4
- package/lib/node/features/html-render/lib/renderer/index.js +69 -6
- package/lib/node/features/html-render/lib/renderer/spa.d.ts +2 -2
- package/lib/node/features/html-render/lib/renderer/spa.js +4 -6
- package/lib/node/features/html-render/lib/renderer/ssr.d.ts +2 -2
- package/lib/node/features/html-render/lib/renderer/ssr.js +5 -6
- package/lib/node/features/html-render/lib/renderer/types.d.ts +8 -5
- package/lib/node/features/html-render/server.d.ts +1 -1
- package/lib/node/features/index.js +1 -3
- package/lib/node/features/model/index.d.ts +1 -13
- package/lib/node/features/model/runtime.d.ts +3 -3
- package/lib/node/features/model/runtime.js +2 -0
- package/lib/node/features/model/shuvi-app.d.ts +2 -2
- package/lib/node/features/on-demand-compile-page/index.d.ts +1 -13
- package/lib/node/features/on-demand-compile-page/onDemandRouteManager.d.ts +3 -3
- package/lib/node/paths.js +0 -2
- package/lib/node/shuvi-runtime-server.d.ts +18 -0
- package/lib/node/shuvi-runtime-server.js +2 -0
- package/lib/node/shuvi-type-extensions-node.d.ts +0 -6
- package/lib/node/targets/react/bundler/index.d.ts +1 -13
- package/lib/node/targets/react/index.d.ts +2 -26
- package/lib/node/targets/react/index.js +2 -2
- package/lib/node/targets/react/model/index.d.ts +6 -0
- package/lib/node/targets/react/{redox-react → model}/index.js +7 -6
- package/lib/shared/appTypes.d.ts +4 -2
- package/lib/shared/renderTypes.d.ts +6 -5
- package/lib/shared/routeTypes.d.ts +4 -9
- package/package.json +14 -14
- package/esm/shuvi-app/react/redox-react/runtime.d.ts +0 -8
- package/esm/shuvi-app/shuvi-runtime-server.d.ts +0 -6
- package/esm/shuvi-app/shuvi-runtime-server.js +0 -1
- package/lib/node/features/webpack-watch-wait-for-file-builder/index.d.ts +0 -16
- package/lib/node/features/webpack-watch-wait-for-file-builder/index.js +0 -25
- package/lib/node/features/webpack-watch-wait-for-file-builder/webpack-watch-wait-for-file-builder-plugin.d.ts +0 -12
- package/lib/node/features/webpack-watch-wait-for-file-builder/webpack-watch-wait-for-file-builder-plugin.js +0 -32
- package/lib/node/targets/react/redox-react/index.d.ts +0 -18
package/esm/shared/appTypes.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IPageRouteRecord, IAppData, IAppState } from '@shuvi/platform-shared/shared';
|
|
2
2
|
import { Application } from '@shuvi/platform-shared/shuvi-app/application';
|
|
3
|
+
import type { ShuviRequest } from '@shuvi/service';
|
|
3
4
|
export interface CreateAppServer {
|
|
4
5
|
(options: {
|
|
5
|
-
req:
|
|
6
|
+
req: ShuviRequest;
|
|
6
7
|
ssr: boolean;
|
|
8
|
+
isDev: boolean;
|
|
7
9
|
}): Application;
|
|
8
10
|
}
|
|
9
11
|
export interface CreateAppClient {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { IManifest } from '@shuvi/toolpack/lib/webpack/types';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import type { ShuviRequest } from '@shuvi/service';
|
|
3
|
+
import { Response, IApplication, IAppData } from '@shuvi/platform-shared/shared';
|
|
4
|
+
export declare type IRenderViewOptions = {
|
|
4
5
|
app: IApplication;
|
|
5
|
-
req?: IRequest;
|
|
6
6
|
};
|
|
7
|
-
export interface IRenderOptions extends
|
|
7
|
+
export interface IRenderOptions extends IRenderViewOptions {
|
|
8
8
|
}
|
|
9
9
|
export interface IView<RenderOption extends IRenderOptions = any, RenderResult = void> {
|
|
10
10
|
renderApp(options: RenderOption): RenderResult;
|
|
@@ -35,8 +35,9 @@ export interface IClientRendererOptions<ExtraAppData = {}> extends IRenderOption
|
|
|
35
35
|
appData: IAppData<ExtraAppData>;
|
|
36
36
|
}
|
|
37
37
|
export interface IServerRendererOptions extends IRenderOptions {
|
|
38
|
+
req: ShuviRequest;
|
|
38
39
|
manifest: IManifest;
|
|
39
|
-
|
|
40
|
+
isDev?: boolean;
|
|
40
41
|
}
|
|
41
42
|
export interface IViewClient<ExtraAppData = {}> extends IView<IClientRendererOptions<ExtraAppData>> {
|
|
42
43
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { IRequestHandlerWithNext } from '@shuvi/service';
|
|
3
|
-
import { IResponse, IRequest } from '@shuvi/service';
|
|
1
|
+
import { ShuviRequest, ShuviResponse, ShuviRequestHandler } from '@shuvi/service';
|
|
4
2
|
export interface IApiReq {
|
|
5
|
-
pathname: string;
|
|
6
|
-
query: IURLQuery;
|
|
7
|
-
params: IURLParams;
|
|
8
3
|
cookies: {
|
|
9
4
|
[key: string]: string;
|
|
10
5
|
};
|
|
@@ -12,7 +7,7 @@ export interface IApiReq {
|
|
|
12
7
|
[key: string]: any;
|
|
13
8
|
};
|
|
14
9
|
}
|
|
15
|
-
export declare type IApiRequest =
|
|
10
|
+
export declare type IApiRequest = ShuviRequest & IApiReq;
|
|
16
11
|
export declare type Send<T> = (body: T) => void;
|
|
17
12
|
export declare type IApiRes<T = any> = {
|
|
18
13
|
send: Send<T>;
|
|
@@ -21,7 +16,7 @@ export declare type IApiRes<T = any> = {
|
|
|
21
16
|
redirect(url: string): IApiRes<T>;
|
|
22
17
|
redirect(status: number, url: string): IApiRes<T>;
|
|
23
18
|
};
|
|
24
|
-
export declare type IApiResponse<T = any> =
|
|
19
|
+
export declare type IApiResponse<T = any> = ShuviResponse & IApiRes<T>;
|
|
25
20
|
export declare type IApiRequestHandler<T = any> = (req: IApiRequest, res: IApiResponse<T>) => void | Promise<void>;
|
|
26
21
|
export interface IApiConfig {
|
|
27
22
|
api?: {
|
|
@@ -35,7 +30,7 @@ export interface IApiHandler {
|
|
|
35
30
|
config?: IApiConfig;
|
|
36
31
|
}
|
|
37
32
|
export interface IMiddlewareConfig {
|
|
38
|
-
default:
|
|
33
|
+
default: ShuviRequestHandler;
|
|
39
34
|
}
|
|
40
35
|
export declare type IApiRoutes = {
|
|
41
36
|
path: string;
|
|
@@ -8,12 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { getRoutes } from '@shuvi/app/core/platform';
|
|
11
|
-
import { runPreload, runLoaders, getRouteMatchesWithInvalidLoader,
|
|
11
|
+
import { runPreload, runLoaders, getRouteMatchesWithInvalidLoader, isRedirect, isResponse } from '@shuvi/platform-shared/shared';
|
|
12
12
|
import application, { Application } from '@shuvi/platform-shared/shuvi-app/application';
|
|
13
13
|
import { createRouter, createBrowserHistory, createHashHistory } from '@shuvi/router';
|
|
14
14
|
import pageLoaders from '@shuvi/app/files/page-loaders';
|
|
15
15
|
import { historyMode } from '@shuvi/app/files/routerConfig';
|
|
16
16
|
import { SHUVI_ERROR } from '@shuvi/shared/lib/constants';
|
|
17
|
+
import { serializeServerError } from '../helper/serializeServerError';
|
|
17
18
|
let app;
|
|
18
19
|
export { Application };
|
|
19
20
|
export const createApp = ({ routes, appData, appComponent }) => {
|
|
@@ -21,7 +22,7 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
21
22
|
if (app) {
|
|
22
23
|
return app;
|
|
23
24
|
}
|
|
24
|
-
const {
|
|
25
|
+
const { appState, ssr } = appData;
|
|
25
26
|
let history;
|
|
26
27
|
if (historyMode === 'hash') {
|
|
27
28
|
history = createHashHistory();
|
|
@@ -38,14 +39,14 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
38
39
|
AppComponent: appComponent,
|
|
39
40
|
router
|
|
40
41
|
});
|
|
42
|
+
const loadersData = app.getLoadersData();
|
|
41
43
|
const hasHydrateData = Object.keys(loadersData).length > 0;
|
|
42
|
-
const loaderManager = getLoaderManager();
|
|
43
44
|
let shouldHydrate = ssr && hasHydrateData;
|
|
44
|
-
let hasServerError = app.error
|
|
45
|
+
let hasServerError = !!app.error;
|
|
45
46
|
router.beforeResolve((to, from, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
47
|
if (shouldHydrate) {
|
|
47
48
|
shouldHydrate = false;
|
|
48
|
-
|
|
49
|
+
app.setLoadersData(loadersData);
|
|
49
50
|
return next();
|
|
50
51
|
}
|
|
51
52
|
if (hasServerError) {
|
|
@@ -53,12 +54,11 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
53
54
|
return next();
|
|
54
55
|
}
|
|
55
56
|
if (!to.matches.length) {
|
|
56
|
-
app.
|
|
57
|
+
app.setError(SHUVI_ERROR.PAGE_NOT_FOUND);
|
|
57
58
|
next();
|
|
58
59
|
return;
|
|
59
60
|
}
|
|
60
61
|
const matches = getRouteMatchesWithInvalidLoader(to, from, pageLoaders);
|
|
61
|
-
let isPreloadError = false;
|
|
62
62
|
try {
|
|
63
63
|
const loaderDatas = yield new Promise((resolve, reject) => {
|
|
64
64
|
let value;
|
|
@@ -79,11 +79,9 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
79
79
|
runPreload(to)
|
|
80
80
|
.then(tryResolve)
|
|
81
81
|
.catch(err => {
|
|
82
|
-
isPreloadError = true;
|
|
83
82
|
reject(err);
|
|
84
83
|
});
|
|
85
84
|
runLoaders(matches, pageLoaders, {
|
|
86
|
-
isServer: false,
|
|
87
85
|
query: to.query,
|
|
88
86
|
getAppContext: () => app.context
|
|
89
87
|
})
|
|
@@ -96,7 +94,7 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
96
94
|
tryResolve();
|
|
97
95
|
});
|
|
98
96
|
});
|
|
99
|
-
|
|
97
|
+
app.setLoadersData(loaderDatas);
|
|
100
98
|
}
|
|
101
99
|
catch (error) {
|
|
102
100
|
if (isRedirect(error)) {
|
|
@@ -104,22 +102,19 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
104
102
|
return;
|
|
105
103
|
}
|
|
106
104
|
if (isResponse(error) && error.status >= 400 && error.status < 600) {
|
|
107
|
-
app.
|
|
105
|
+
app.setError({
|
|
108
106
|
code: error.status,
|
|
109
107
|
message: error.data
|
|
110
108
|
});
|
|
111
109
|
next();
|
|
112
110
|
return;
|
|
113
111
|
}
|
|
114
|
-
app.error.
|
|
115
|
-
code: SHUVI_ERROR.APP_ERROR.code,
|
|
116
|
-
message: error.message || isPreloadError ? 'Preload Error' : 'Loader Error'
|
|
117
|
-
});
|
|
112
|
+
app.setError(serializeServerError(error, process.env.NODE_ENV === 'development'));
|
|
118
113
|
next();
|
|
119
114
|
return;
|
|
120
115
|
}
|
|
121
116
|
next(() => {
|
|
122
|
-
app.
|
|
117
|
+
app.clearError();
|
|
123
118
|
});
|
|
124
119
|
}));
|
|
125
120
|
return app;
|
|
@@ -9,12 +9,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import routes from '@shuvi/app/files/routes';
|
|
11
11
|
import { getRoutes, app as AppComponent } from '@shuvi/app/core/platform';
|
|
12
|
-
import { runLoaders, getRouteMatchesWithInvalidLoader, isResponse, isRedirect
|
|
12
|
+
import { runLoaders, getRouteMatchesWithInvalidLoader, isResponse, isRedirect } from '@shuvi/platform-shared/shared';
|
|
13
13
|
import pageLoaders from '@shuvi/app/files/page-loaders';
|
|
14
14
|
import application from '@shuvi/platform-shared/shuvi-app/application';
|
|
15
15
|
import { createRouter, createMemoryHistory } from '@shuvi/router';
|
|
16
|
+
import chalk from '@shuvi/utils/lib/chalk';
|
|
17
|
+
import { serializeServerError } from '../helper/serializeServerError';
|
|
16
18
|
export const createApp = options => {
|
|
17
|
-
const { req, ssr } = options;
|
|
19
|
+
const { req, ssr, isDev } = options;
|
|
18
20
|
const history = createMemoryHistory({
|
|
19
21
|
initialEntries: [(req && req.url) || '/'],
|
|
20
22
|
initialIndex: 0
|
|
@@ -24,18 +26,16 @@ export const createApp = options => {
|
|
|
24
26
|
routes: getRoutes(routes)
|
|
25
27
|
});
|
|
26
28
|
let app;
|
|
27
|
-
const loaderManager = getLoaderManager();
|
|
28
29
|
if (ssr) {
|
|
29
30
|
router.beforeResolve((to, from, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
31
|
const matches = getRouteMatchesWithInvalidLoader(to, from, pageLoaders);
|
|
31
32
|
try {
|
|
32
33
|
const loaderResult = yield runLoaders(matches, pageLoaders, {
|
|
33
|
-
isServer: true,
|
|
34
34
|
req,
|
|
35
35
|
query: to.query,
|
|
36
36
|
getAppContext: () => app.context
|
|
37
37
|
});
|
|
38
|
-
|
|
38
|
+
app.setLoadersData(loaderResult);
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
41
|
if (isRedirect(error)) {
|
|
@@ -43,16 +43,17 @@ export const createApp = options => {
|
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
if (isResponse(error) && error.status >= 400 && error.status < 600) {
|
|
46
|
-
app.
|
|
46
|
+
app.setError({
|
|
47
47
|
code: error.status,
|
|
48
48
|
message: error.data
|
|
49
49
|
});
|
|
50
50
|
next();
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
53
|
+
if (isDev) {
|
|
54
|
+
console.error(chalk.red('error') + ' - ' + error.stack);
|
|
55
|
+
}
|
|
56
|
+
app.setError(serializeServerError(error, isDev));
|
|
56
57
|
next();
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
@@ -24,7 +24,6 @@ SOFTWARE.
|
|
|
24
24
|
export declare type HotDevClient = {
|
|
25
25
|
sendMessage: (data: any) => void;
|
|
26
26
|
subscribeToHmrEvent: (handler: any) => void;
|
|
27
|
-
reportRuntimeError: (err: any) => void;
|
|
28
27
|
};
|
|
29
28
|
export default function connect(options: {
|
|
30
29
|
launchEditorEndpoint: string;
|
|
@@ -34,9 +34,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
34
34
|
});
|
|
35
35
|
};
|
|
36
36
|
// @ts-nocheck
|
|
37
|
-
import * as ErrorOverlay from 'react-error-overlay';
|
|
38
37
|
import stripAnsi from 'strip-ansi';
|
|
39
38
|
import formatWebpackMessages from '@shuvi/toolpack/lib/utils/formatWebpackMessages';
|
|
39
|
+
import { startReportingRuntimeErrors, stopReportingRuntimeErrors, onBuildError, onBuildOk, onRefresh } from '@shuvi/error-overlay';
|
|
40
40
|
import { DEV_SOCKET_TIMEOUT_MS } from '@shuvi/shared/esm/constants';
|
|
41
41
|
import { connectHMR, addMessageListener, sendMessage } from './websocket';
|
|
42
42
|
// This alternative WebpackDevServer combines the functionality of:
|
|
@@ -52,33 +52,14 @@ import { connectHMR, addMessageListener, sendMessage } from './websocket';
|
|
|
52
52
|
let hadRuntimeError = false;
|
|
53
53
|
let customHmrEventHandler;
|
|
54
54
|
export default function connect(options) {
|
|
55
|
-
|
|
56
|
-
ErrorOverlay.setEditorHandler(function editorHandler({ fileName, lineNumber, colNumber }) {
|
|
57
|
-
// Resolve invalid paths coming from react-error-overlay
|
|
58
|
-
const resolvedFilename = fileName.replace(/^webpack:\/\/[^/]+/ /* webpack://namaspcae/resourcepath */, '');
|
|
59
|
-
fetch(options.launchEditorEndpoint +
|
|
60
|
-
'?fileName=' +
|
|
61
|
-
window.encodeURIComponent(resolvedFilename) +
|
|
62
|
-
'&lineNumber=' +
|
|
63
|
-
window.encodeURIComponent(lineNumber || 1) +
|
|
64
|
-
'&colNumber=' +
|
|
65
|
-
window.encodeURIComponent(colNumber || 1));
|
|
66
|
-
});
|
|
67
|
-
// We need to keep track of if there has been a runtime error.
|
|
68
|
-
// Essentially, we cannot guarantee application state was not corrupted by the
|
|
69
|
-
// runtime error. To prevent confusing behavior, we forcibly reload the entire
|
|
70
|
-
// application. This is handled below when we are notified of a compile (code
|
|
71
|
-
// change).
|
|
72
|
-
// See https://github.com/facebook/create-react-app/issues/3096
|
|
73
|
-
ErrorOverlay.startReportingRuntimeErrors({
|
|
55
|
+
startReportingRuntimeErrors({
|
|
74
56
|
onError: function () {
|
|
75
57
|
hadRuntimeError = true;
|
|
76
58
|
}
|
|
77
59
|
});
|
|
78
60
|
if (module.hot && typeof module.hot.dispose === 'function') {
|
|
79
61
|
module.hot.dispose(function () {
|
|
80
|
-
|
|
81
|
-
ErrorOverlay.stopReportingRuntimeErrors();
|
|
62
|
+
stopReportingRuntimeErrors();
|
|
82
63
|
});
|
|
83
64
|
}
|
|
84
65
|
connectHMR(Object.assign(Object.assign({}, options), { log: true }));
|
|
@@ -104,9 +85,6 @@ export default function connect(options) {
|
|
|
104
85
|
},
|
|
105
86
|
subscribeToHmrEvent(handler) {
|
|
106
87
|
customHmrEventHandler = handler;
|
|
107
|
-
},
|
|
108
|
-
reportRuntimeError(err) {
|
|
109
|
-
ErrorOverlay.reportRuntimeError(err);
|
|
110
88
|
}
|
|
111
89
|
};
|
|
112
90
|
}
|
|
@@ -123,8 +101,11 @@ function clearOutdatedErrors() {
|
|
|
123
101
|
}
|
|
124
102
|
}
|
|
125
103
|
let startLatency = undefined;
|
|
126
|
-
function onFastRefresh() {
|
|
127
|
-
|
|
104
|
+
function onFastRefresh(hasUpdates) {
|
|
105
|
+
onBuildOk();
|
|
106
|
+
if (hasUpdates) {
|
|
107
|
+
onRefresh();
|
|
108
|
+
}
|
|
128
109
|
if (startLatency) {
|
|
129
110
|
const endLatency = Date.now();
|
|
130
111
|
const latency = endLatency - startLatency;
|
|
@@ -139,10 +120,10 @@ function handleSuccess() {
|
|
|
139
120
|
hasCompileErrors = false;
|
|
140
121
|
// Attempt to apply hot updates or reload.
|
|
141
122
|
if (isHotUpdate) {
|
|
142
|
-
tryApplyUpdates(function onHotUpdateSuccess() {
|
|
123
|
+
tryApplyUpdates(function onHotUpdateSuccess(hasUpdates) {
|
|
143
124
|
// Only dismiss it when we're sure it's a hot update.
|
|
144
125
|
// Otherwise it would flicker right before the reload.
|
|
145
|
-
onFastRefresh();
|
|
126
|
+
onFastRefresh(hasUpdates);
|
|
146
127
|
});
|
|
147
128
|
}
|
|
148
129
|
}
|
|
@@ -169,16 +150,18 @@ function handleWarnings(warnings) {
|
|
|
169
150
|
}
|
|
170
151
|
// Attempt to apply hot updates or reload.
|
|
171
152
|
if (isHotUpdate) {
|
|
172
|
-
tryApplyUpdates(function onSuccessfulHotUpdate() {
|
|
153
|
+
tryApplyUpdates(function onSuccessfulHotUpdate(hasUpdates) {
|
|
173
154
|
// Only dismiss it when we're sure it's a hot update.
|
|
174
155
|
// Otherwise it would flicker right before the reload.
|
|
175
|
-
|
|
176
|
-
onFastRefresh();
|
|
156
|
+
onFastRefresh(hasUpdates);
|
|
177
157
|
});
|
|
178
158
|
}
|
|
179
159
|
}
|
|
180
160
|
// Compilation with errors (e.g. syntax error or missing modules).
|
|
181
161
|
function handleErrors(errors) {
|
|
162
|
+
if (!Boolean(errors && errors.length)) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
182
165
|
clearOutdatedErrors();
|
|
183
166
|
isFirstCompilation = false;
|
|
184
167
|
hasCompileErrors = true;
|
|
@@ -188,7 +171,7 @@ function handleErrors(errors) {
|
|
|
188
171
|
warnings: []
|
|
189
172
|
});
|
|
190
173
|
// Only show the first error.
|
|
191
|
-
|
|
174
|
+
onBuildError(formatted.errors[0]);
|
|
192
175
|
// Also log them to the console.
|
|
193
176
|
if (typeof console !== 'undefined' && typeof console.error === 'function') {
|
|
194
177
|
for (var i = 0; i < formatted.errors.length; i++) {
|
|
@@ -196,11 +179,6 @@ function handleErrors(errors) {
|
|
|
196
179
|
}
|
|
197
180
|
}
|
|
198
181
|
}
|
|
199
|
-
function tryDismissErrorOverlay() {
|
|
200
|
-
if (!hasCompileErrors) {
|
|
201
|
-
ErrorOverlay.dismissBuildError();
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
182
|
// There is a newer version of the code available.
|
|
205
183
|
function handleAvailableHash(hash) {
|
|
206
184
|
// Update last known compilation hash.
|
|
@@ -286,7 +264,7 @@ function tryApplyUpdates(onHotUpdateSuccess) {
|
|
|
286
264
|
return;
|
|
287
265
|
}
|
|
288
266
|
if (!isUpdateAvailable() || !canApplyUpdates()) {
|
|
289
|
-
|
|
267
|
+
onBuildOk();
|
|
290
268
|
// HMR failed, need to refresh
|
|
291
269
|
const hmrStatus = module.hot.status();
|
|
292
270
|
if (hmrStatus === 'abort' || hmrStatus === 'fail') {
|
|
@@ -295,24 +273,25 @@ function tryApplyUpdates(onHotUpdateSuccess) {
|
|
|
295
273
|
return;
|
|
296
274
|
}
|
|
297
275
|
function handleApplyUpdates(err, updatedModules) {
|
|
298
|
-
const
|
|
299
|
-
if (
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
hadRuntimeError = true;
|
|
307
|
-
}
|
|
276
|
+
const hasUpdates = Boolean(updatedModules === null || updatedModules === void 0 ? void 0 : updatedModules.length);
|
|
277
|
+
if (hadRuntimeError) {
|
|
278
|
+
hadRuntimeError = false;
|
|
279
|
+
window.location.reload();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (err) {
|
|
283
|
+
hadRuntimeError = true;
|
|
308
284
|
}
|
|
309
285
|
if (typeof onHotUpdateSuccess === 'function') {
|
|
310
286
|
// Maybe we want to do something.
|
|
311
|
-
onHotUpdateSuccess();
|
|
287
|
+
onHotUpdateSuccess(hasUpdates);
|
|
312
288
|
}
|
|
313
289
|
if (isUpdateAvailable()) {
|
|
314
290
|
// While we were updating, there was a new update! Do it again.
|
|
315
|
-
tryApplyUpdates(onHotUpdateSuccess);
|
|
291
|
+
tryApplyUpdates(hasUpdates ? onBuildOk : onHotUpdateSuccess);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
onBuildOk();
|
|
316
295
|
}
|
|
317
296
|
}
|
|
318
297
|
try {
|
|
@@ -3,7 +3,6 @@ export declare function sendMessage(data: any): any;
|
|
|
3
3
|
export declare type HotDevClient = {
|
|
4
4
|
sendMessage: (data: any) => void;
|
|
5
5
|
subscribeToHmrEvent?: (handler: any) => void;
|
|
6
|
-
reportRuntimeError?: (err: any) => void;
|
|
7
6
|
};
|
|
8
7
|
export declare function connectHMR(options: {
|
|
9
8
|
path: string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import stripAnsi from 'strip-ansi';
|
|
3
|
+
function errorToJSON(err) {
|
|
4
|
+
return {
|
|
5
|
+
code: 500,
|
|
6
|
+
message: stripAnsi(err.message),
|
|
7
|
+
name: err.name,
|
|
8
|
+
source: 'server',
|
|
9
|
+
stack: err.stack
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function serializeServerError(err, dev) {
|
|
13
|
+
if (dev) {
|
|
14
|
+
return errorToJSON(err);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
code: 500,
|
|
18
|
+
message: 'Internal Server Error',
|
|
19
|
+
name: 'Internal Server Error'
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { IApplication } from '@shuvi/platform-shared/shared';
|
|
3
|
-
export default function AppContainer({
|
|
3
|
+
export default function AppContainer({ app, children }: React.PropsWithChildren<{
|
|
4
4
|
app: IApplication;
|
|
5
|
-
|
|
6
|
-
}): JSX.Element;
|
|
5
|
+
}>): JSX.Element;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { errorModel } from '@shuvi/platform-shared/shared';
|
|
3
|
-
import { createContainer } from '@shuvi/redox-react';
|
|
4
3
|
import { AppProvider } from './applicationContext';
|
|
5
4
|
import ErrorPage from './ErrorPage';
|
|
6
5
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
7
|
-
|
|
6
|
+
import { Provider, useSharedModel } from './store';
|
|
8
7
|
function ErrorGuard({ children = null }) {
|
|
9
8
|
const [errorState] = useSharedModel(errorModel);
|
|
10
9
|
if (errorState.error !== undefined) {
|
|
@@ -12,10 +11,10 @@ function ErrorGuard({ children = null }) {
|
|
|
12
11
|
}
|
|
13
12
|
return <>{children}</>;
|
|
14
13
|
}
|
|
15
|
-
export default function AppContainer({
|
|
14
|
+
export default function AppContainer({ app, children }) {
|
|
16
15
|
return (<ErrorBoundary>
|
|
17
16
|
<AppProvider app={app}>
|
|
18
|
-
<Provider
|
|
17
|
+
<Provider store={app.store}>
|
|
19
18
|
<ErrorGuard>{children}</ErrorGuard>
|
|
20
19
|
</Provider>
|
|
21
20
|
</AppProvider>
|
|
@@ -13,8 +13,7 @@ import { loadRouteComponent } from './loadRouteComponent';
|
|
|
13
13
|
export default function getRoutes(routes) {
|
|
14
14
|
const getRoutesWithRequire = (routes) => routes.map(x => {
|
|
15
15
|
const originalRoute = Object.assign({}, x);
|
|
16
|
-
const { __componentRawRequest__, __import__, __resolveWeak__, children } = originalRoute,
|
|
17
|
-
const route = Object.assign({}, rest);
|
|
16
|
+
const { __componentRawRequest__, __import__, __resolveWeak__, children } = originalRoute, route = __rest(originalRoute, ["__componentRawRequest__", "__import__", "__resolveWeak__", "children"]);
|
|
18
17
|
if (children) {
|
|
19
18
|
route.children = getRoutesWithRequire(children);
|
|
20
19
|
}
|
|
@@ -23,7 +22,10 @@ export default function getRoutes(routes) {
|
|
|
23
22
|
modules: [__componentRawRequest__]
|
|
24
23
|
})));
|
|
25
24
|
}
|
|
26
|
-
|
|
25
|
+
if (__componentRawRequest__) {
|
|
26
|
+
route.__componentRawRequest__ = __componentRawRequest__;
|
|
27
|
+
}
|
|
28
|
+
return route;
|
|
27
29
|
});
|
|
28
30
|
const routesWithRequire = getRoutesWithRequire(routes || []);
|
|
29
31
|
return routesWithRequire;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type {
|
|
2
|
+
import type { RedoxStore } from '@shuvi/redox';
|
|
3
3
|
export declare const RedoxWrapper: (App: any, appContext: {
|
|
4
|
-
|
|
4
|
+
store: RedoxStore;
|
|
5
5
|
}) => {
|
|
6
|
-
(
|
|
6
|
+
(): JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { RedoxRoot } from '@shuvi/redox-react';
|
|
3
3
|
export const RedoxWrapper = (App, appContext) => {
|
|
4
|
-
function RedoxAppWrapper(
|
|
5
|
-
return (<RedoxRoot
|
|
6
|
-
<App
|
|
4
|
+
function RedoxAppWrapper() {
|
|
5
|
+
return (<RedoxRoot store={appContext.store}>
|
|
6
|
+
<App />
|
|
7
7
|
</RedoxRoot>);
|
|
8
8
|
}
|
|
9
9
|
RedoxAppWrapper.displayName = 'RedoxAppWrapper';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RedoxStore } from '@shuvi/redox';
|
|
2
|
+
declare module '@shuvi/runtime' {
|
|
3
|
+
interface CustomAppContext {
|
|
4
|
+
store: RedoxStore;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
declare const _default: import("@shuvi/platform-shared/shared").IPluginInstance<import("@shuvi/platform-shared/shared").RuntimePluginHooks, void>;
|
|
8
|
+
export default _default;
|
|
@@ -7,12 +7,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { createRuntimePluginAfter } from '@shuvi/platform-shared/shared';
|
|
11
11
|
import { RedoxWrapper } from './RedoxWrapper';
|
|
12
|
-
|
|
12
|
+
// this needs to be run last
|
|
13
|
+
export default createRuntimePluginAfter({
|
|
13
14
|
appComponent: (App, appContext) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
15
|
return RedoxWrapper(App, {
|
|
15
|
-
|
|
16
|
+
store: appContext.store
|
|
16
17
|
});
|
|
17
18
|
})
|
|
19
|
+
}, {
|
|
20
|
+
name: 'model-react'
|
|
18
21
|
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
declare const Provider: (props: import("react").PropsWithChildren<{
|
|
3
|
+
store?: import("@shuvi/redox").RedoxStore | undefined;
|
|
4
|
+
}>) => JSX.Element, useSharedModel: import("@shuvi/redox-react/esm/types").IUseModel, useStaticModel: import("@shuvi/redox-react/esm/types").IUseStaticModel;
|
|
5
|
+
export { Provider, useSharedModel, useStaticModel };
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import { IAppState } from '@shuvi/platform-shared/shared';
|
|
2
1
|
import { IHtmlTag, IViewClient, IViewServer } from '../../shared';
|
|
3
2
|
export { IHtmlTag };
|
|
4
3
|
export declare type IReactAppData = {
|
|
5
|
-
appProps?: Record<string, any>;
|
|
6
|
-
errorProps?: {
|
|
7
|
-
notFound: boolean;
|
|
8
|
-
};
|
|
9
4
|
dynamicIds?: Array<string | number>;
|
|
10
|
-
appState?: IAppState;
|
|
11
|
-
loadersData: any;
|
|
12
5
|
};
|
|
13
6
|
export declare type IReactServerView = IViewServer<IReactAppData>;
|
|
14
7
|
export declare type IReactClientView = IViewClient<IReactAppData>;
|
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
import { useMatchedRoute } from '@shuvi/router-react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { loaderModel } from '@shuvi/platform-shared/shared';
|
|
3
|
+
import { useStaticModel } from './store';
|
|
4
4
|
export const noLoaderMessage = 'Warning: no loader found. Please make sure the page component where `useLoaderData` is called has a `loader` export.';
|
|
5
|
+
const hasOwn = Object.prototype.hasOwnProperty;
|
|
5
6
|
export const useLoaderData = () => {
|
|
6
|
-
var _a;
|
|
7
7
|
const currentMatch = useMatchedRoute();
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const id = currentMatch.route.id;
|
|
9
|
+
// we don't need to watch the model change, cause it always change with
|
|
10
|
+
// matched route
|
|
11
|
+
const [state] = useStaticModel(loaderModel);
|
|
12
|
+
if (!hasOwn.call(state.current.dataByRouteId, id)) {
|
|
12
13
|
throw Error(noLoaderMessage);
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
const [_, forceUpdate] = useReducer(state => state * -1, 1);
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
const cancel = loaderManager.subscribe(() => {
|
|
18
|
-
const newData = loaderManager.getData(id);
|
|
19
|
-
if (newData !== data) {
|
|
20
|
-
dataRef.current = newData;
|
|
21
|
-
forceUpdate();
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
return cancel;
|
|
25
|
-
}, []);
|
|
26
|
-
return dataRef.current;
|
|
15
|
+
return state.current.dataByRouteId[id];
|
|
27
16
|
};
|