@shuvi/platform-web 1.0.39 → 1.0.42

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.
@@ -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 && hasHydrateData;
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
- app.setLoadersData(loadersData);
52
- return next();
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) {
@@ -113,10 +111,7 @@ export const createApp = ({ routes, appData, appComponent }) => {
113
111
  window.location.replace(location);
114
112
  }
115
113
  else {
116
- next({
117
- path: location,
118
- replace: true
119
- });
114
+ next(location);
120
115
  }
121
116
  runLoadersTrace.setAttribute(SHUVI_CLIENT_RUN_LOADERS.attrs.errorType.name, 'redirect');
122
117
  runLoadersTrace.stop();
@@ -132,6 +127,8 @@ export const createApp = ({ routes, appData, appComponent }) => {
132
127
  runLoadersTrace.stop();
133
128
  return;
134
129
  }
130
+ runLoadersTrace.setAttribute(SHUVI_CLIENT_RUN_LOADERS.attrs.errorType.name, 'unexpectedError');
131
+ runLoadersTrace.stop();
135
132
  // If loader throws a error, we need to rethrow it
136
133
  app.setError({
137
134
  message: SHUVI_ERROR.CLIENT_ERROR.message,
@@ -141,8 +138,6 @@ export const createApp = ({ routes, appData, appComponent }) => {
141
138
  next(() => {
142
139
  throw error;
143
140
  });
144
- runLoadersTrace.setAttribute(SHUVI_CLIENT_RUN_LOADERS.attrs.errorType.name, 'unexpectedError');
145
- runLoadersTrace.stop();
146
141
  return;
147
142
  }
148
143
  next(() => {
@@ -51,6 +51,8 @@ export const createApp = options => {
51
51
  if (isRedirect(error)) {
52
52
  const location = error.headers.get('Location');
53
53
  const status = error.status;
54
+ // server side redirect is different from regular route redirect because it has the extra data - statusCode
55
+ // So it won't change route target, but just store the redirect location in state
54
56
  next({
55
57
  path: pathToString(to),
56
58
  replace: true,
@@ -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 { clientRenderTrace } from '../entry/client/trace';
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>{children}</ErrorGuard>
20
+ <ErrorGuard>
21
+ <Trace>{children}</Trace>
22
+ </ErrorGuard>
59
23
  </Provider>
60
24
  </ErrorBoundary>
61
25
  </AppProvider>);
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ export declare function useTrace(): void;
3
+ export declare function Trace({ children }: React.PropsWithChildren<{}>): JSX.Element;
@@ -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]: res.statusCode
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/shared/constants/trace");
19
- const { SHUVI_SERVER_RUN_MIDDLEWARE_ROUTES } = trace_1.SERVER_REQUEST.events;
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
- return yield runMiddleware(middlewares[i]);
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
- // shuold never reach here
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.39",
3
+ "version": "1.0.42",
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.39",
76
- "@shuvi/hook": "1.0.39",
77
- "@shuvi/platform-shared": "1.0.39",
78
- "@shuvi/router": "1.0.39",
79
- "@shuvi/router-react": "1.0.39",
80
- "@shuvi/runtime": "1.0.39",
81
- "@shuvi/shared": "1.0.39",
82
- "@shuvi/toolpack": "1.0.39",
83
- "@shuvi/utils": "1.0.39",
75
+ "@shuvi/error-overlay": "1.0.42",
76
+ "@shuvi/hook": "1.0.42",
77
+ "@shuvi/platform-shared": "1.0.42",
78
+ "@shuvi/router": "1.0.42",
79
+ "@shuvi/router-react": "1.0.42",
80
+ "@shuvi/runtime": "1.0.42",
81
+ "@shuvi/shared": "1.0.42",
82
+ "@shuvi/toolpack": "1.0.42",
83
+ "@shuvi/utils": "1.0.42",
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.39"
101
+ "@shuvi/service": "1.0.42"
102
102
  },
103
103
  "devDependencies": {
104
104
  "@shuvi/service": "workspace:*",