@shuvi/platform-web 1.0.39 → 1.0.41
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/shuvi-app/app/client.js +7 -9
- package/esm/shuvi-app/react/AppContainer.jsx +4 -40
- package/esm/shuvi-app/react/Trace.d.ts +3 -0
- package/esm/shuvi-app/react/Trace.jsx +43 -0
- package/lib/node/features/filesystem-routes/api/middleware.js +3 -1
- package/lib/node/features/filesystem-routes/middleware/middleware.js +14 -3
- package/lib/node/features/html-render/lib/getPageMiddleware.js +2 -1
- package/package.json +11 -11
|
@@ -43,16 +43,14 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
43
43
|
});
|
|
44
44
|
const loadersData = app.getLoadersData();
|
|
45
45
|
const hasHydrateData = Object.keys(loadersData).length > 0;
|
|
46
|
-
let shouldHydrate = ssr
|
|
47
|
-
let hasServerError = !!app.error;
|
|
46
|
+
let shouldHydrate = !!ssr;
|
|
48
47
|
router.beforeResolve((to, from, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
|
+
// when hydrating, we will never run loaders, but just use the data from server
|
|
49
49
|
if (shouldHydrate) {
|
|
50
50
|
shouldHydrate = false;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (hasServerError) {
|
|
55
|
-
hasServerError = false;
|
|
51
|
+
if (hasHydrateData) {
|
|
52
|
+
app.setLoadersData(loadersData);
|
|
53
|
+
}
|
|
56
54
|
return next();
|
|
57
55
|
}
|
|
58
56
|
if (!to.matches.length) {
|
|
@@ -132,6 +130,8 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
132
130
|
runLoadersTrace.stop();
|
|
133
131
|
return;
|
|
134
132
|
}
|
|
133
|
+
runLoadersTrace.setAttribute(SHUVI_CLIENT_RUN_LOADERS.attrs.errorType.name, 'unexpectedError');
|
|
134
|
+
runLoadersTrace.stop();
|
|
135
135
|
// If loader throws a error, we need to rethrow it
|
|
136
136
|
app.setError({
|
|
137
137
|
message: SHUVI_ERROR.CLIENT_ERROR.message,
|
|
@@ -141,8 +141,6 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
141
141
|
next(() => {
|
|
142
142
|
throw error;
|
|
143
143
|
});
|
|
144
|
-
runLoadersTrace.setAttribute(SHUVI_CLIENT_RUN_LOADERS.attrs.errorType.name, 'unexpectedError');
|
|
145
|
-
runLoadersTrace.stop();
|
|
146
144
|
return;
|
|
147
145
|
}
|
|
148
146
|
next(() => {
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useCurrentRoute, useRouter } from '@shuvi/router-react';
|
|
3
2
|
import { errorModel, errorModelName } from '@shuvi/platform-shared/shared';
|
|
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
|
-
import {
|
|
9
|
-
import { CLIENT_RENDER } from '@shuvi/shared/constants/trace';
|
|
10
|
-
const { SHUVI_NAVIGATION_TRIGGERED, SHUVI_NAVIGATION_DONE, SHUVI_PAGE_READY } = CLIENT_RENDER.events;
|
|
7
|
+
import { Trace } from './Trace';
|
|
11
8
|
function ErrorGuard({ children = null }) {
|
|
12
9
|
const errorState = useSharedModel(errorModelName, errorModel);
|
|
13
10
|
const { error, hasError } = errorState;
|
|
@@ -16,46 +13,13 @@ function ErrorGuard({ children = null }) {
|
|
|
16
13
|
}
|
|
17
14
|
return <>{children}</>;
|
|
18
15
|
}
|
|
19
|
-
const uuid = () => {
|
|
20
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
21
|
-
var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
22
|
-
return v.toString(16);
|
|
23
|
-
});
|
|
24
|
-
};
|
|
25
|
-
function useTrace() {
|
|
26
|
-
const router = useRouter();
|
|
27
|
-
const route = useCurrentRoute();
|
|
28
|
-
let navigationTrace = React.useRef();
|
|
29
|
-
React.useEffect(() => {
|
|
30
|
-
clientRenderTrace.traceChild(SHUVI_PAGE_READY.name).stop();
|
|
31
|
-
router.beforeEach((to, from, next) => {
|
|
32
|
-
const fromPath = `${from.pathname}${from.search}`;
|
|
33
|
-
const toPath = `${to.pathname}${to.search}`;
|
|
34
|
-
const navigationId = uuid();
|
|
35
|
-
const traceAttrs = {
|
|
36
|
-
[SHUVI_NAVIGATION_DONE.attrs.from.name]: fromPath,
|
|
37
|
-
[SHUVI_NAVIGATION_DONE.attrs.to.name]: toPath,
|
|
38
|
-
[SHUVI_NAVIGATION_DONE.attrs.navigationId.name]: navigationId
|
|
39
|
-
};
|
|
40
|
-
clientRenderTrace
|
|
41
|
-
.traceChild(SHUVI_NAVIGATION_TRIGGERED.name, traceAttrs)
|
|
42
|
-
.stop();
|
|
43
|
-
navigationTrace.current = clientRenderTrace.traceChild(SHUVI_NAVIGATION_DONE.name);
|
|
44
|
-
navigationTrace.current.setAttributes(traceAttrs);
|
|
45
|
-
next();
|
|
46
|
-
});
|
|
47
|
-
}, []);
|
|
48
|
-
React.useEffect(() => {
|
|
49
|
-
var _a;
|
|
50
|
-
(_a = navigationTrace.current) === null || _a === void 0 ? void 0 : _a.stop();
|
|
51
|
-
}, [route]);
|
|
52
|
-
}
|
|
53
16
|
export default function AppContainer({ app, children }) {
|
|
54
|
-
useTrace();
|
|
55
17
|
return (<AppProvider app={app}>
|
|
56
18
|
<ErrorBoundary>
|
|
57
19
|
<Provider store={app.store}>
|
|
58
|
-
<ErrorGuard>
|
|
20
|
+
<ErrorGuard>
|
|
21
|
+
<Trace>{children}</Trace>
|
|
22
|
+
</ErrorGuard>
|
|
59
23
|
</Provider>
|
|
60
24
|
</ErrorBoundary>
|
|
61
25
|
</AppProvider>);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useCurrentRoute, useRouter } from '@shuvi/router-react';
|
|
3
|
+
import { clientRenderTrace } from '../entry/client/trace';
|
|
4
|
+
import { CLIENT_RENDER } from '@shuvi/shared/constants/trace';
|
|
5
|
+
const { SHUVI_NAVIGATION_TRIGGERED, SHUVI_NAVIGATION_DONE, SHUVI_PAGE_READY } = CLIENT_RENDER.events;
|
|
6
|
+
const uuid = () => {
|
|
7
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
8
|
+
var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
9
|
+
return v.toString(16);
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
export function useTrace() {
|
|
13
|
+
const router = useRouter();
|
|
14
|
+
const route = useCurrentRoute();
|
|
15
|
+
let navigationTrace = React.useRef();
|
|
16
|
+
React.useEffect(() => {
|
|
17
|
+
clientRenderTrace.traceChild(SHUVI_PAGE_READY.name).stop();
|
|
18
|
+
router.beforeEach((to, from, next) => {
|
|
19
|
+
const fromPath = `${from.pathname}${from.search}`;
|
|
20
|
+
const toPath = `${to.pathname}${to.search}`;
|
|
21
|
+
const navigationId = uuid();
|
|
22
|
+
const traceAttrs = {
|
|
23
|
+
[SHUVI_NAVIGATION_DONE.attrs.from.name]: fromPath,
|
|
24
|
+
[SHUVI_NAVIGATION_DONE.attrs.to.name]: toPath,
|
|
25
|
+
[SHUVI_NAVIGATION_DONE.attrs.navigationId.name]: navigationId
|
|
26
|
+
};
|
|
27
|
+
clientRenderTrace
|
|
28
|
+
.traceChild(SHUVI_NAVIGATION_TRIGGERED.name, traceAttrs)
|
|
29
|
+
.stop();
|
|
30
|
+
navigationTrace.current = clientRenderTrace.traceChild(SHUVI_NAVIGATION_DONE.name);
|
|
31
|
+
navigationTrace.current.setAttributes(traceAttrs);
|
|
32
|
+
next();
|
|
33
|
+
});
|
|
34
|
+
}, []);
|
|
35
|
+
React.useEffect(() => {
|
|
36
|
+
var _a;
|
|
37
|
+
(_a = navigationTrace.current) === null || _a === void 0 ? void 0 : _a.stop();
|
|
38
|
+
}, [route]);
|
|
39
|
+
}
|
|
40
|
+
export function Trace({ children = null }) {
|
|
41
|
+
useTrace();
|
|
42
|
+
return <>{children}</>;
|
|
43
|
+
}
|
|
@@ -43,9 +43,11 @@ function middleware(_ctx) {
|
|
|
43
43
|
catch (error) {
|
|
44
44
|
runApiMiddlewareTrace.setAttributes({
|
|
45
45
|
[SHUVI_SERVER_RUN_API_MIDDLEWARE.attrs.error.name]: true,
|
|
46
|
-
[SHUVI_SERVER_RUN_API_MIDDLEWARE.attrs.statusCode.name]:
|
|
46
|
+
[SHUVI_SERVER_RUN_API_MIDDLEWARE.attrs.statusCode.name]: 500
|
|
47
47
|
});
|
|
48
|
+
runApiMiddlewareTrace.stop();
|
|
48
49
|
next(error);
|
|
50
|
+
return;
|
|
49
51
|
}
|
|
50
52
|
runApiMiddlewareTrace.setAttributes({
|
|
51
53
|
[SHUVI_SERVER_RUN_API_MIDDLEWARE.attrs.error.name]: false,
|
|
@@ -15,8 +15,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.middleware = void 0;
|
|
16
16
|
const router_1 = require("@shuvi/router");
|
|
17
17
|
const resources_1 = __importDefault(require("@shuvi/service/lib/resources"));
|
|
18
|
-
const trace_1 = require("@shuvi/
|
|
19
|
-
const
|
|
18
|
+
const trace_1 = require("@shuvi/service/lib/trace");
|
|
19
|
+
const trace_2 = require("@shuvi/shared/constants/trace");
|
|
20
|
+
const { SHUVI_SERVER_RUN_MIDDLEWARE_ROUTES } = trace_2.SERVER_REQUEST.events;
|
|
20
21
|
function middleware(_api) {
|
|
21
22
|
return function (req, res, next) {
|
|
22
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -64,7 +65,17 @@ function middleware(_api) {
|
|
|
64
65
|
return next(err);
|
|
65
66
|
}
|
|
66
67
|
});
|
|
67
|
-
|
|
68
|
+
yield runMiddleware(middlewares[i]);
|
|
69
|
+
// if a middleware directly ends the response, the middlewareRoutesTrace will be recorded here
|
|
70
|
+
if (middlewareRoutesTrace.status === trace_1.SpanStatus.Started) {
|
|
71
|
+
middlewareRoutesTrace.setAttributes({
|
|
72
|
+
[SHUVI_SERVER_RUN_MIDDLEWARE_ROUTES.attrs.error.name]: false,
|
|
73
|
+
[SHUVI_SERVER_RUN_MIDDLEWARE_ROUTES.attrs.statusCode.name]: res.statusCode,
|
|
74
|
+
[SHUVI_SERVER_RUN_MIDDLEWARE_ROUTES.attrs.headersSent.name]: res.headersSent
|
|
75
|
+
});
|
|
76
|
+
middlewareRoutesTrace.stop();
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
68
79
|
}
|
|
69
80
|
catch (err) {
|
|
70
81
|
/** Catch error from the whole function */
|
|
@@ -57,7 +57,7 @@ function createPageHandler(serverPluginContext) {
|
|
|
57
57
|
sendHtmlHookTrace.stop();
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
60
|
-
//
|
|
60
|
+
// should never reach here
|
|
61
61
|
throw new Error('Unexpected reponse type from renderToHTML');
|
|
62
62
|
}
|
|
63
63
|
});
|
|
@@ -90,6 +90,7 @@ function getPageMiddleware(api) {
|
|
|
90
90
|
runPageMiddlewareTrace.stop();
|
|
91
91
|
}
|
|
92
92
|
catch (error) {
|
|
93
|
+
// should never reach here except for server bundle broken
|
|
93
94
|
runPageMiddlewareTrace.setAttributes({
|
|
94
95
|
[SHUVI_SERVER_RUN_PAGE_MIDDLEWARE.attrs.error.name]: true,
|
|
95
96
|
[SHUVI_SERVER_RUN_PAGE_MIDDLEWARE.attrs.statusCode.name]: res.statusCode
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shuvi/platform-web",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.41",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/shuvijs/shuvi.git",
|
|
@@ -72,15 +72,15 @@
|
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@next/react-refresh-utils": "12.1.6",
|
|
75
|
-
"@shuvi/error-overlay": "1.0.
|
|
76
|
-
"@shuvi/hook": "1.0.
|
|
77
|
-
"@shuvi/platform-shared": "1.0.
|
|
78
|
-
"@shuvi/router": "1.0.
|
|
79
|
-
"@shuvi/router-react": "1.0.
|
|
80
|
-
"@shuvi/runtime": "1.0.
|
|
81
|
-
"@shuvi/shared": "1.0.
|
|
82
|
-
"@shuvi/toolpack": "1.0.
|
|
83
|
-
"@shuvi/utils": "1.0.
|
|
75
|
+
"@shuvi/error-overlay": "1.0.41",
|
|
76
|
+
"@shuvi/hook": "1.0.41",
|
|
77
|
+
"@shuvi/platform-shared": "1.0.41",
|
|
78
|
+
"@shuvi/router": "1.0.41",
|
|
79
|
+
"@shuvi/router-react": "1.0.41",
|
|
80
|
+
"@shuvi/runtime": "1.0.41",
|
|
81
|
+
"@shuvi/shared": "1.0.41",
|
|
82
|
+
"@shuvi/toolpack": "1.0.41",
|
|
83
|
+
"@shuvi/utils": "1.0.41",
|
|
84
84
|
"content-type": "1.0.4",
|
|
85
85
|
"core-js": "3.6.5",
|
|
86
86
|
"doura": "0.0.13",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"whatwg-fetch": "3.0.0"
|
|
99
99
|
},
|
|
100
100
|
"peerDependencies": {
|
|
101
|
-
"@shuvi/service": "1.0.
|
|
101
|
+
"@shuvi/service": "1.0.41"
|
|
102
102
|
},
|
|
103
103
|
"devDependencies": {
|
|
104
104
|
"@shuvi/service": "workspace:*",
|