@shuvi/platform-web 0.0.1-rc.34 → 1.0.0-rc.2

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 (238) hide show
  1. package/esm/shared/appTypes.d.ts +15 -0
  2. package/esm/shared/appTypes.js +1 -0
  3. package/esm/shared/configTypes.d.ts +14 -0
  4. package/esm/shared/configTypes.js +1 -0
  5. package/esm/shared/index.d.ts +5 -0
  6. package/esm/shared/index.js +5 -0
  7. package/esm/shared/renderTypes.d.ts +44 -0
  8. package/esm/shared/renderTypes.js +1 -0
  9. package/esm/shared/routeTypes.d.ts +47 -0
  10. package/esm/shared/routeTypes.js +1 -0
  11. package/esm/shared/serverTypes.d.ts +6 -0
  12. package/esm/shared/serverTypes.js +1 -0
  13. package/esm/shuvi-app/app/client.d.ts +2 -0
  14. package/esm/shuvi-app/app/client.js +125 -0
  15. package/esm/shuvi-app/app/server.d.ts +2 -0
  16. package/esm/shuvi-app/app/server.js +67 -0
  17. package/{shuvi-app → esm/shuvi-app}/dev/webpackHotDevClient.d.ts +0 -0
  18. package/{shuvi-app → esm/shuvi-app}/dev/webpackHotDevClient.js +2 -1
  19. package/esm/shuvi-app/entry/client/app.d.ts +2 -0
  20. package/esm/shuvi-app/entry/client/app.js +57 -0
  21. package/esm/shuvi-app/entry/client/index.d.ts +2 -0
  22. package/esm/shuvi-app/entry/client/index.js +12 -0
  23. package/{shuvi-app → esm/shuvi-app}/entry/client/run.dev.d.ts +0 -0
  24. package/{shuvi-app → esm/shuvi-app}/entry/client/run.dev.js +2 -2
  25. package/{shuvi-app → esm/shuvi-app}/entry/client/run.prod.d.ts +0 -0
  26. package/esm/shuvi-app/entry/client/run.prod.js +3 -0
  27. package/{shuvi-app → esm/shuvi-app}/entry/client/setup-env.d.ts +1 -1
  28. package/esm/shuvi-app/entry/client/setup-env.js +17 -0
  29. package/esm/shuvi-app/entry/server/index.d.ts +6 -0
  30. package/esm/shuvi-app/entry/server/index.js +7 -0
  31. package/esm/shuvi-app/react/AppComponent.d.ts +4 -0
  32. package/esm/shuvi-app/react/AppComponent.jsx +6 -0
  33. package/esm/shuvi-app/react/AppContainer.d.ts +6 -0
  34. package/esm/shuvi-app/react/AppContainer.jsx +23 -0
  35. package/esm/shuvi-app/react/Error.d.ts +5 -0
  36. package/esm/shuvi-app/react/Error.jsx +38 -0
  37. package/esm/shuvi-app/react/ErrorBoundary.d.ts +16 -0
  38. package/esm/shuvi-app/react/ErrorBoundary.jsx +25 -0
  39. package/esm/shuvi-app/react/ErrorPage.d.ts +5 -0
  40. package/esm/shuvi-app/react/ErrorPage.jsx +7 -0
  41. package/esm/shuvi-app/react/Link.d.ts +7 -0
  42. package/esm/shuvi-app/react/Link.jsx +115 -0
  43. package/esm/shuvi-app/react/applicationContext.d.ts +7 -0
  44. package/esm/shuvi-app/react/applicationContext.jsx +10 -0
  45. package/esm/shuvi-app/react/dynamic.d.ts +31 -0
  46. package/esm/shuvi-app/react/dynamic.jsx +62 -0
  47. package/esm/shuvi-app/react/getRoutes.d.ts +2 -0
  48. package/esm/shuvi-app/react/getRoutes.js +31 -0
  49. package/esm/shuvi-app/react/head/head-manager-context.d.ts +2 -0
  50. package/esm/shuvi-app/react/head/head-manager-context.js +2 -0
  51. package/esm/shuvi-app/react/head/head-manager.d.ts +10 -0
  52. package/esm/shuvi-app/react/head/head-manager.js +93 -0
  53. package/esm/shuvi-app/react/head/head.d.ts +33 -0
  54. package/esm/shuvi-app/react/head/head.jsx +178 -0
  55. package/esm/shuvi-app/react/head/index.d.ts +4 -0
  56. package/esm/shuvi-app/react/head/index.js +4 -0
  57. package/esm/shuvi-app/react/head/side-effect.d.ts +30 -0
  58. package/esm/shuvi-app/react/head/side-effect.jsx +44 -0
  59. package/esm/shuvi-app/react/head/types.d.ts +15 -0
  60. package/esm/shuvi-app/react/head/types.js +1 -0
  61. package/esm/shuvi-app/react/index.d.ts +4 -0
  62. package/esm/shuvi-app/react/index.js +4 -0
  63. package/esm/shuvi-app/react/loadRouteComponent.d.ts +4 -0
  64. package/esm/shuvi-app/react/loadRouteComponent.jsx +9 -0
  65. package/esm/shuvi-app/react/loadable/index.d.ts +2 -0
  66. package/esm/shuvi-app/react/loadable/index.js +2 -0
  67. package/esm/shuvi-app/react/loadable/loadable-context.d.ts +4 -0
  68. package/esm/shuvi-app/react/loadable/loadable-context.js +3 -0
  69. package/esm/shuvi-app/react/loadable/loadable.d.ts +30 -0
  70. package/esm/shuvi-app/react/loadable/loadable.js +277 -0
  71. package/esm/shuvi-app/react/redox-react/RedoxWrapper.d.ts +8 -0
  72. package/esm/shuvi-app/react/redox-react/RedoxWrapper.jsx +11 -0
  73. package/esm/shuvi-app/react/redox-react/runtime.d.ts +2 -0
  74. package/esm/shuvi-app/react/redox-react/runtime.js +16 -0
  75. package/esm/shuvi-app/react/shuvi-runtime-api.d.ts +5 -0
  76. package/esm/shuvi-app/react/shuvi-runtime-api.js +5 -0
  77. package/esm/shuvi-app/react/types.d.ts +14 -0
  78. package/esm/shuvi-app/react/types.js +1 -0
  79. package/esm/shuvi-app/react/useLoaderData.d.ts +2 -0
  80. package/esm/shuvi-app/react/useLoaderData.js +27 -0
  81. package/esm/shuvi-app/react/utils/getDisplayName.d.ts +2 -0
  82. package/esm/shuvi-app/react/utils/getDisplayName.js +3 -0
  83. package/esm/shuvi-app/react/utils/requestIdleCallback.d.ts +2 -0
  84. package/esm/shuvi-app/react/utils/requestIdleCallback.js +20 -0
  85. package/esm/shuvi-app/react/utils/useIntersection.d.ts +8 -0
  86. package/esm/shuvi-app/react/utils/useIntersection.jsx +91 -0
  87. package/esm/shuvi-app/react/view/ReactView.client.d.ts +5 -0
  88. package/esm/shuvi-app/react/view/ReactView.client.jsx +64 -0
  89. package/esm/shuvi-app/react/view/ReactView.server.d.ts +4 -0
  90. package/esm/shuvi-app/react/view/ReactView.server.jsx +109 -0
  91. package/esm/shuvi-app/react/view/clientView.d.ts +3 -0
  92. package/esm/shuvi-app/react/view/clientView.js +2 -0
  93. package/esm/shuvi-app/react/view/index.d.ts +2 -0
  94. package/esm/shuvi-app/react/view/index.js +7 -0
  95. package/esm/shuvi-app/react/view/render-action.d.ts +10 -0
  96. package/esm/shuvi-app/react/view/render-action.js +29 -0
  97. package/esm/shuvi-app/react/view/serverView.d.ts +3 -0
  98. package/esm/shuvi-app/react/view/serverView.js +2 -0
  99. package/esm/shuvi-app/react/view/transformRoutes.d.ts +2 -0
  100. package/esm/shuvi-app/react/view/transformRoutes.js +3 -0
  101. package/esm/shuvi-app/shuvi-runtime-index.d.ts +4 -0
  102. package/esm/shuvi-app/shuvi-runtime-index.js +2 -0
  103. package/esm/shuvi-app/shuvi-runtime-server.d.ts +6 -0
  104. package/esm/shuvi-app/shuvi-runtime-server.js +1 -0
  105. package/lib/node/features/custom-server/index.d.ts +4 -0
  106. package/lib/node/features/custom-server/index.js +9 -0
  107. package/lib/node/features/custom-server/server.d.ts +2 -0
  108. package/lib/node/features/custom-server/server.js +28 -0
  109. package/lib/node/features/filesystem-routes/api/apiRouteHandler.d.ts +51 -0
  110. package/lib/node/features/filesystem-routes/api/apiRouteHandler.js +237 -0
  111. package/lib/node/features/filesystem-routes/api/apiRoutes.d.ts +7 -0
  112. package/lib/node/features/filesystem-routes/api/apiRoutes.js +35 -0
  113. package/lib/node/features/filesystem-routes/api/index.d.ts +3 -0
  114. package/lib/node/features/filesystem-routes/api/index.js +7 -0
  115. package/lib/node/features/filesystem-routes/api/middleware.d.ts +2 -0
  116. package/lib/node/features/filesystem-routes/api/middleware.js +44 -0
  117. package/lib/node/features/filesystem-routes/hooks.d.ts +3 -0
  118. package/lib/node/features/filesystem-routes/hooks.js +6 -0
  119. package/lib/node/features/filesystem-routes/index.d.ts +20 -0
  120. package/lib/node/features/filesystem-routes/index.js +180 -0
  121. package/lib/node/features/filesystem-routes/middleware/index.d.ts +2 -0
  122. package/lib/node/features/filesystem-routes/middleware/index.js +7 -0
  123. package/lib/node/features/filesystem-routes/middleware/middleware.d.ts +2 -0
  124. package/lib/node/features/filesystem-routes/middleware/middleware.js +42 -0
  125. package/lib/node/features/filesystem-routes/middleware/routes.d.ts +9 -0
  126. package/lib/node/features/filesystem-routes/middleware/routes.js +34 -0
  127. package/lib/node/features/filesystem-routes/page/index.d.ts +2 -0
  128. package/lib/node/features/filesystem-routes/page/index.js +21 -0
  129. package/lib/node/features/filesystem-routes/page/routes.d.ts +8 -0
  130. package/lib/node/features/filesystem-routes/page/routes.js +83 -0
  131. package/lib/node/features/filesystem-routes/page/store.d.ts +3 -0
  132. package/lib/node/features/filesystem-routes/page/store.js +10 -0
  133. package/lib/node/features/html-render/index.d.ts +19 -0
  134. package/lib/node/features/html-render/index.js +28 -0
  135. package/lib/node/features/html-render/lib/generateFilesByRoutId.d.ts +3 -0
  136. package/lib/node/features/html-render/lib/generateFilesByRoutId.js +13 -0
  137. package/lib/node/features/html-render/lib/getPageMiddleware.d.ts +2 -0
  138. package/lib/node/features/html-render/lib/getPageMiddleware.js +56 -0
  139. package/lib/node/features/html-render/lib/index.d.ts +4 -0
  140. package/lib/node/features/html-render/lib/index.js +23 -0
  141. package/lib/node/features/html-render/lib/pageLoader.d.ts +1 -0
  142. package/lib/node/features/html-render/lib/pageLoader.js +42 -0
  143. package/lib/node/features/html-render/lib/renderToHTML.d.ts +6 -0
  144. package/lib/node/features/html-render/lib/renderToHTML.js +81 -0
  145. package/lib/node/features/html-render/lib/renderer/base.d.ts +17 -0
  146. package/lib/node/features/html-render/lib/renderer/base.js +70 -0
  147. package/lib/node/features/html-render/lib/renderer/htmlTag.d.ts +4 -0
  148. package/lib/node/features/html-render/lib/renderer/htmlTag.js +70 -0
  149. package/lib/node/features/html-render/lib/renderer/index.d.ts +15 -0
  150. package/lib/node/features/html-render/lib/renderer/index.js +48 -0
  151. package/lib/node/features/html-render/lib/renderer/spa.d.ts +5 -0
  152. package/lib/node/features/html-render/lib/renderer/spa.js +26 -0
  153. package/lib/node/features/html-render/lib/renderer/ssr.d.ts +5 -0
  154. package/lib/node/features/html-render/lib/renderer/ssr.js +70 -0
  155. package/lib/node/features/html-render/lib/renderer/types.d.ts +20 -0
  156. package/lib/node/features/html-render/lib/renderer/types.js +2 -0
  157. package/lib/node/features/html-render/lib/viewTemplate.d.ts +5 -0
  158. package/lib/node/features/html-render/lib/viewTemplate.js +37 -0
  159. package/lib/node/features/html-render/server.d.ts +2 -0
  160. package/lib/node/features/html-render/server.js +9 -0
  161. package/lib/node/features/html-render/serverHooks.d.ts +10 -0
  162. package/lib/node/features/html-render/serverHooks.js +13 -0
  163. package/lib/node/features/html-render/shuvi-app.d.ts +6 -0
  164. package/lib/node/features/html-render/shuvi-app.js +2 -0
  165. package/lib/node/features/index.d.ts +32 -0
  166. package/lib/node/features/index.js +25 -0
  167. package/lib/node/features/main/buildHtml.d.ts +8 -0
  168. package/lib/node/features/main/buildHtml.js +64 -0
  169. package/lib/node/features/main/generateResource.d.ts +3 -0
  170. package/lib/node/features/main/generateResource.js +56 -0
  171. package/lib/node/features/main/index.d.ts +3 -0
  172. package/lib/node/features/main/index.js +82 -0
  173. package/lib/node/features/middlewares.d.ts +4 -0
  174. package/lib/node/features/middlewares.js +23 -0
  175. package/lib/node/features/model/index.d.ts +21 -0
  176. package/lib/node/features/model/index.js +54 -0
  177. package/lib/node/features/model/runtime.d.ts +13 -0
  178. package/lib/node/features/model/runtime.js +47 -0
  179. package/lib/node/features/model/server.d.ts +3 -0
  180. package/lib/node/features/model/server.js +12 -0
  181. package/lib/node/features/model/shuvi-app.d.ts +6 -0
  182. package/lib/node/features/model/shuvi-app.js +2 -0
  183. package/lib/node/features/on-demand-compile-page/emptyComponent.d.ts +1 -0
  184. package/lib/node/features/on-demand-compile-page/emptyComponent.js +7 -0
  185. package/lib/node/features/on-demand-compile-page/index.d.ts +15 -0
  186. package/lib/node/features/on-demand-compile-page/index.js +36 -0
  187. package/lib/node/features/on-demand-compile-page/onDemandRouteManager.d.ts +11 -0
  188. package/lib/node/features/on-demand-compile-page/onDemandRouteManager.js +104 -0
  189. package/lib/node/index.d.ts +6 -0
  190. package/lib/node/index.js +38 -0
  191. package/lib/{paths.d.ts → node/paths.d.ts} +1 -2
  192. package/lib/node/paths.js +36 -0
  193. package/lib/node/shuvi-type-extensions-node.d.ts +42 -0
  194. package/lib/node/shuvi-type-extensions-node.js +3 -0
  195. package/lib/node/targets/react/bundler/index.d.ts +16 -0
  196. package/lib/node/targets/react/bundler/index.js +102 -0
  197. package/lib/node/targets/react/index.d.ts +32 -0
  198. package/lib/node/targets/react/index.js +28 -0
  199. package/lib/node/targets/react/redox-react/index.d.ts +18 -0
  200. package/lib/node/targets/react/redox-react/index.js +50 -0
  201. package/lib/shared/appTypes.d.ts +15 -0
  202. package/lib/shared/appTypes.js +2 -0
  203. package/lib/shared/configTypes.d.ts +14 -0
  204. package/lib/shared/configTypes.js +2 -0
  205. package/lib/shared/index.d.ts +5 -0
  206. package/lib/shared/index.js +21 -0
  207. package/lib/shared/renderTypes.d.ts +44 -0
  208. package/lib/shared/renderTypes.js +2 -0
  209. package/lib/shared/routeTypes.d.ts +47 -0
  210. package/lib/shared/routeTypes.js +2 -0
  211. package/lib/shared/serverTypes.d.ts +6 -0
  212. package/lib/shared/serverTypes.js +2 -0
  213. package/package.json +78 -15
  214. package/shuvi-type-extensions-node.d.ts +2 -0
  215. package/shuvi-type-extensions-runtime.d.ts +36 -0
  216. package/lib/index.d.ts +0 -3
  217. package/lib/index.js +0 -44
  218. package/lib/paths.js +0 -7
  219. package/shuvi-app/application/client/create-application-factory.d.ts +0 -3
  220. package/shuvi-app/application/client/create-application-factory.js +0 -70
  221. package/shuvi-app/application/client/create-application-history-browser.d.ts +0 -1
  222. package/shuvi-app/application/client/create-application-history-browser.js +0 -3
  223. package/shuvi-app/application/client/create-application-history-hash.d.ts +0 -1
  224. package/shuvi-app/application/client/create-application-history-hash.js +0 -3
  225. package/shuvi-app/application/client/create-application-history-memory.d.ts +0 -1
  226. package/shuvi-app/application/client/create-application-history-memory.js +0 -3
  227. package/shuvi-app/application/server/create-application-spa.d.ts +0 -2
  228. package/shuvi-app/application/server/create-application-spa.js +0 -8
  229. package/shuvi-app/application/server/create-application.d.ts +0 -2
  230. package/shuvi-app/application/server/create-application.js +0 -25
  231. package/shuvi-app/entry/client/index.d.ts +0 -1
  232. package/shuvi-app/entry/client/index.js +0 -11
  233. package/shuvi-app/entry/client/run.prod.js +0 -3
  234. package/shuvi-app/entry/client/setup-app.d.ts +0 -3
  235. package/shuvi-app/entry/client/setup-app.js +0 -38
  236. package/shuvi-app/entry/client/setup-env.js +0 -27
  237. package/shuvi-app/entry/server/index.d.ts +0 -6
  238. package/shuvi-app/entry/server/index.js +0 -7
@@ -0,0 +1,25 @@
1
+ import * as React from 'react';
2
+ import { SHUVI_ERROR } from '@shuvi/shared/lib/constants';
3
+ import ErrorPage from './ErrorPage';
4
+ class ErrorBoundary extends React.PureComponent {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.state = { error: null };
8
+ }
9
+ componentDidCatch(error,
10
+ // Loosely typed because it depends on the React version and was
11
+ // accidentally excluded in some versions.
12
+ errorInfo) {
13
+ this.setState({ error });
14
+ console.error('the error is below: \n', error);
15
+ if (errorInfo && errorInfo.componentStack) {
16
+ console.error('the componentStack is below: \n', errorInfo.componentStack);
17
+ }
18
+ }
19
+ render() {
20
+ return this.state.error ? (
21
+ // The component has to be unmounted or else it would continue to error
22
+ <ErrorPage code={SHUVI_ERROR.APP_ERROR.code} message={SHUVI_ERROR.APP_ERROR.message}/>) : this.props.children;
23
+ }
24
+ }
25
+ export { ErrorBoundary };
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ export default function ErrorPage({ code, message }: {
3
+ code?: number;
4
+ message?: string;
5
+ }): JSX.Element;
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ import error from './Error';
3
+ import userError from '@shuvi/app/core/error';
4
+ const Error = userError || error;
5
+ export default function ErrorPage({ code, message }) {
6
+ return <Error errorCode={code} errorDesc={message}/>;
7
+ }
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import { LinkProps } from '@shuvi/router-react';
3
+ export declare const Link: ({ prefetch, onMouseEnter, to, ref, ...rest }: LinkWrapperProps) => JSX.Element;
4
+ interface LinkWrapperProps extends LinkProps {
5
+ ref?: any;
6
+ }
7
+ export {};
@@ -0,0 +1,115 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __rest = (this && this.__rest) || function (s, e) {
11
+ var t = {};
12
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
13
+ t[p] = s[p];
14
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
15
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
17
+ t[p[i]] = s[p[i]];
18
+ }
19
+ return t;
20
+ };
21
+ import * as React from 'react';
22
+ import { Link as LinkFromRouterReact, RouterContext } from '@shuvi/router-react';
23
+ import { getFilesOfRoute } from '@shuvi/platform-shared/shared';
24
+ import useIntersection from './utils/useIntersection';
25
+ const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/;
26
+ const prefetched = {};
27
+ function hasSupportPrefetch() {
28
+ try {
29
+ const link = document.createElement('link');
30
+ return link.relList.supports('prefetch');
31
+ }
32
+ catch (e) {
33
+ return false;
34
+ }
35
+ }
36
+ function prefetchViaDom(href, id, as) {
37
+ return new Promise((res, rej) => {
38
+ const selector = `
39
+ link[rel="prefetch"][href^="${href}"],
40
+ script[src^="${href}"]`;
41
+ if (document.querySelector(selector)) {
42
+ return res();
43
+ }
44
+ const link = document.createElement('link');
45
+ // The order of property assignment here is intentional:
46
+ if (as)
47
+ link.as = as;
48
+ link.rel = `prefetch`;
49
+ link.onload = res;
50
+ link.onerror = rej;
51
+ link.dataset.id = id;
52
+ // `href` should always be last:
53
+ link.href = href;
54
+ document.head.appendChild(link);
55
+ });
56
+ }
57
+ function prefetchFn(router, to) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ const files = getFilesOfRoute(router, to);
60
+ if (process.env.NODE_ENV !== 'production')
61
+ return;
62
+ if (typeof window === 'undefined')
63
+ return;
64
+ const canPrefetch = hasSupportPrefetch();
65
+ yield Promise.all(canPrefetch
66
+ ? files.js.map(({ url, id }) => prefetchViaDom(url, id, 'script'))
67
+ : []);
68
+ });
69
+ }
70
+ const isAbsoluteUrl = (url) => {
71
+ return ABSOLUTE_URL_REGEX.test(url);
72
+ };
73
+ export const Link = function LinkWithPrefetch(_a) {
74
+ var { prefetch, onMouseEnter, to, ref } = _a, rest = __rest(_a, ["prefetch", "onMouseEnter", "to", "ref"]);
75
+ const isHrefValid = typeof to === 'string' && !isAbsoluteUrl(to);
76
+ const previousHref = React.useRef(to);
77
+ const [setIntersectionRef, isVisible, resetVisible] = useIntersection({});
78
+ const { router } = React.useContext(RouterContext);
79
+ const setRef = React.useCallback((el) => {
80
+ // Before the link getting observed, check if visible state need to be reset
81
+ if (isHrefValid && previousHref.current !== to) {
82
+ resetVisible();
83
+ previousHref.current = to;
84
+ }
85
+ if (isHrefValid && prefetch !== false)
86
+ setIntersectionRef(el);
87
+ if (ref) {
88
+ if (typeof ref === 'function')
89
+ ref(el);
90
+ else if (typeof ref === 'object') {
91
+ ref.current = el;
92
+ }
93
+ }
94
+ }, [to, isHrefValid, prefetch, resetVisible, setIntersectionRef, ref]);
95
+ React.useEffect(() => {
96
+ const shouldPrefetch = isHrefValid && prefetch !== false && isVisible;
97
+ if (shouldPrefetch && !prefetched[to]) {
98
+ prefetchFn(router, to);
99
+ prefetched[to] = true;
100
+ }
101
+ }, [to, prefetch, isVisible]);
102
+ const childProps = {
103
+ ref: setRef,
104
+ onMouseEnter: (e) => {
105
+ if (typeof onMouseEnter === 'function') {
106
+ onMouseEnter(e);
107
+ }
108
+ if (isHrefValid && !prefetched[to]) {
109
+ prefetchFn(router, to);
110
+ prefetched[to] = true;
111
+ }
112
+ }
113
+ };
114
+ return <LinkFromRouterReact to={to} {...rest} {...childProps}/>;
115
+ };
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ import { IApplication } from '@shuvi/platform-shared/shared';
3
+ export declare const ApplicationContext: React.Context<IApplication>;
4
+ export declare function AppProvider({ app, children }: React.PropsWithChildren<{
5
+ app: IApplication;
6
+ }>): JSX.Element;
7
+ export declare function useApp(): IApplication;
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ export const ApplicationContext = React.createContext(null);
3
+ export function AppProvider({ app, children }) {
4
+ return (<ApplicationContext.Provider value={app}>
5
+ {children}
6
+ </ApplicationContext.Provider>);
7
+ }
8
+ export function useApp() {
9
+ return React.useContext(ApplicationContext);
10
+ }
@@ -0,0 +1,31 @@
1
+ import * as React from 'react';
2
+ export declare type LoaderComponent<P = {}> = Promise<React.ComponentType<P> | {
3
+ default: React.ComponentType<P>;
4
+ }>;
5
+ export declare type Loader<P = {}> = () => LoaderComponent<P>;
6
+ export declare type LoadableGeneratedOptions = {
7
+ webpack?(): string[];
8
+ modules?: string[];
9
+ };
10
+ export declare type LoadableBaseOptions<P = {}> = LoadableGeneratedOptions & {
11
+ loading?: ({ error, isLoading, pastDelay }: {
12
+ error?: Error | null;
13
+ isLoading?: boolean;
14
+ pastDelay?: boolean;
15
+ timedOut?: boolean;
16
+ }) => JSX.Element | null;
17
+ loader?: Loader<P>;
18
+ ssr?: boolean;
19
+ };
20
+ export declare type DynamicOptions<P = {}> = LoadableBaseOptions<P>;
21
+ export declare type LoaderFn<P = {}> = (opts: DynamicOptions<P>) => React.ComponentType<P>;
22
+ export declare type LoadableComponent<P = {}> = React.ComponentType<P>;
23
+ export declare function noSSR<P = {}>(LoadableInitializer: LoaderFn<P>, dynamicOptions: DynamicOptions<P>): React.ComponentType<P> | (() => JSX.Element);
24
+ /**
25
+ * ES2020 [dynamic import()](https://github.com/tc39/proposal-dynamic-import) for JavaScript
26
+ *
27
+ * @param dynamicOptions {@link DynamicOptions} | {@link Loader}
28
+ * @param options {@link DynamicOptions}
29
+ * @returns React.ComponentType
30
+ */
31
+ export default function dynamic<P = {}>(dynamicOptions: DynamicOptions<P> | Loader<P>, options?: DynamicOptions<P>): React.ComponentType<P>;
@@ -0,0 +1,62 @@
1
+ import * as React from 'react';
2
+ import Loadable from './loadable';
3
+ const isServerSide = typeof window === 'undefined';
4
+ export function noSSR(LoadableInitializer, dynamicOptions) {
5
+ // Removing webpack and modules means react-loadable won't try preloading
6
+ delete dynamicOptions.webpack;
7
+ delete dynamicOptions.modules;
8
+ // This check is neccesary to prevent react-loadable from initializing on the server
9
+ if (!isServerSide) {
10
+ return LoadableInitializer(dynamicOptions);
11
+ }
12
+ const Loading = dynamicOptions.loading;
13
+ // This will only be rendered on the server side
14
+ return () => (<Loading error={null} isLoading pastDelay={false} timedOut={false}/>);
15
+ }
16
+ /**
17
+ * ES2020 [dynamic import()](https://github.com/tc39/proposal-dynamic-import) for JavaScript
18
+ *
19
+ * @param dynamicOptions {@link DynamicOptions} | {@link Loader}
20
+ * @param options {@link DynamicOptions}
21
+ * @returns React.ComponentType
22
+ */
23
+ export default function dynamic(dynamicOptions, options) {
24
+ let loadableFn = Loadable;
25
+ let loadableOptions = {
26
+ // A loading component is not required, so we default it
27
+ loading: ({ error, isLoading, pastDelay }) => {
28
+ if (!pastDelay)
29
+ return null;
30
+ if (process.env.NODE_ENV === 'development') {
31
+ if (isLoading) {
32
+ return null;
33
+ }
34
+ if (error) {
35
+ return (<p>
36
+ {error.message}
37
+ <br />
38
+ {error.stack}
39
+ </p>);
40
+ }
41
+ }
42
+ return null;
43
+ }
44
+ };
45
+ if (typeof dynamicOptions === 'function') {
46
+ loadableOptions.loader = dynamicOptions;
47
+ // Support for having first argument being options, eg: dynamic({loader: import('../hello-world')})
48
+ }
49
+ else if (typeof dynamicOptions === 'object') {
50
+ loadableOptions = Object.assign(Object.assign({}, loadableOptions), dynamicOptions);
51
+ }
52
+ // Support for passing options, eg: dynamic(import('../hello-world'), {loading: () => <p>Loading something</p>})
53
+ loadableOptions = Object.assign(Object.assign({}, loadableOptions), options);
54
+ if (typeof loadableOptions.ssr === 'boolean') {
55
+ if (!loadableOptions.ssr) {
56
+ delete loadableOptions.ssr;
57
+ return noSSR(loadableFn, loadableOptions);
58
+ }
59
+ delete loadableOptions.ssr;
60
+ }
61
+ return loadableFn(loadableOptions);
62
+ }
@@ -0,0 +1,2 @@
1
+ import { IPageRouteRecord, IRawPageRouteRecord } from '@shuvi/platform-shared/shared';
2
+ export default function getRoutes(routes: IRawPageRouteRecord[]): IPageRouteRecord[];
@@ -0,0 +1,31 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { loadRouteComponent } from './loadRouteComponent';
13
+ export default function getRoutes(routes) {
14
+ const getRoutesWithRequire = (routes) => routes.map(x => {
15
+ const originalRoute = Object.assign({}, x);
16
+ const { __componentSource__, __componentSourceWithAffix__, __import__, __resolveWeak__, children } = originalRoute, rest = __rest(originalRoute, ["__componentSource__", "__componentSourceWithAffix__", "__import__", "__resolveWeak__", "children"]);
17
+ const route = Object.assign({}, rest);
18
+ if (children) {
19
+ route.children = getRoutesWithRequire(children);
20
+ }
21
+ if (__componentSourceWithAffix__ && __import__) {
22
+ route.component = loadRouteComponent(__import__, {
23
+ webpack: __resolveWeak__,
24
+ modules: [__componentSourceWithAffix__]
25
+ });
26
+ }
27
+ return Object.assign({ __componentSourceWithAffix__, __resolveWeak__ }, route);
28
+ });
29
+ const routesWithRequire = getRoutesWithRequire(routes || []);
30
+ return routesWithRequire;
31
+ }
@@ -0,0 +1,2 @@
1
+ import * as React from 'react';
2
+ export declare const HeadManagerContext: React.Context<any>;
@@ -0,0 +1,2 @@
1
+ import * as React from 'react';
2
+ export const HeadManagerContext = React.createContext(null);
@@ -0,0 +1,10 @@
1
+ import { HeadState } from './types';
2
+ export default class HeadManager {
3
+ private _pedningPromise;
4
+ private _head;
5
+ constructor();
6
+ updateHead(head: HeadState): void;
7
+ private _doUpdateHead;
8
+ private _updateTitle;
9
+ private _updateElements;
10
+ }
@@ -0,0 +1,93 @@
1
+ // Based on https://github.com/zeit/next.js
2
+ // License: https://github.com/zeit/next.js/blob/977bf8d9ebd2845241b8689317f36e4e487f39d0/license.md
3
+ import { SHUVI_HEAD_ATTRIBUTE } from './head';
4
+ export default class HeadManager {
5
+ constructor() {
6
+ this._pedningPromise = null;
7
+ this.updateHead = this.updateHead.bind(this);
8
+ }
9
+ updateHead(head) {
10
+ this._head = head;
11
+ if (this._pedningPromise) {
12
+ return;
13
+ }
14
+ this._pedningPromise = Promise.resolve().then(() => {
15
+ this._pedningPromise = null;
16
+ this._doUpdateHead();
17
+ });
18
+ }
19
+ _doUpdateHead() {
20
+ const tags = {};
21
+ this._head.forEach(h => {
22
+ (tags[h.tagName] || (tags[h.tagName] = [])).push(h);
23
+ });
24
+ if (tags.title) {
25
+ this._updateTitle(tags.title[0]);
26
+ }
27
+ const types = ['meta', 'base', 'link', 'style', 'script'];
28
+ types.forEach(type => {
29
+ this._updateElements(type, tags[type] || []);
30
+ });
31
+ }
32
+ _updateTitle({ attrs }) {
33
+ const title = attrs.textContent || '';
34
+ if (title !== document.title)
35
+ document.title = title;
36
+ const titleEle = document.getElementsByTagName('title')[0];
37
+ if (titleEle) {
38
+ assignAttributes(titleEle, attrs);
39
+ }
40
+ }
41
+ _updateElements(type, tags) {
42
+ const headEl = document.getElementsByTagName('head')[0];
43
+ const oldNodes = headEl.querySelectorAll(`${type}[${SHUVI_HEAD_ATTRIBUTE}='true']`);
44
+ const oldTags = Array.prototype.slice.call(oldNodes);
45
+ let divideElement = null;
46
+ if (oldTags.length) {
47
+ divideElement = oldTags[oldTags.length - 1].nextElementSibling;
48
+ }
49
+ const newTags = tags.map(tagToDOM).filter(newTag => {
50
+ for (let k = 0, len = oldTags.length; k < len; k++) {
51
+ const oldTag = oldTags[k];
52
+ if (oldTag.isEqualNode(newTag)) {
53
+ oldTags.splice(k, 1);
54
+ return false;
55
+ }
56
+ }
57
+ return true;
58
+ });
59
+ oldTags.forEach(t => t.parentNode.removeChild(t));
60
+ newTags.forEach(t => {
61
+ if (divideElement) {
62
+ headEl.insertBefore(t, divideElement);
63
+ }
64
+ else {
65
+ headEl.appendChild(t);
66
+ }
67
+ });
68
+ }
69
+ }
70
+ function assignAttributes(el, attrs) {
71
+ for (const a in attrs) {
72
+ if (!Object.prototype.hasOwnProperty.call(attrs, a))
73
+ continue;
74
+ if (a === 'textContent')
75
+ continue;
76
+ // we don't render undefined props to the DOM
77
+ if (attrs[a] === undefined)
78
+ continue;
79
+ el.setAttribute(a.toLowerCase(), attrs[a]);
80
+ }
81
+ }
82
+ function tagToDOM({ tagName, attrs, innerHTML }) {
83
+ const el = document.createElement(tagName);
84
+ assignAttributes(el, attrs);
85
+ const { textContent } = attrs;
86
+ if (innerHTML) {
87
+ el.innerHTML = innerHTML;
88
+ }
89
+ else if (textContent) {
90
+ el.textContent = textContent;
91
+ }
92
+ return el;
93
+ }
@@ -0,0 +1,33 @@
1
+ import * as React from 'react';
2
+ import { HeadState } from './types';
3
+ export declare const SHUVI_HEAD_ATTRIBUTE = "data-shuvi-head";
4
+ /**
5
+ * This component injects elements to `<head>` of your page.
6
+ * To avoid duplicated `tags` in `<head>` you can use the `key` property, which will make sure every tag is only rendered once.
7
+ *
8
+ * ```ts
9
+ * import { Head } from "@shuvi/runtime";
10
+ *
11
+ * function IndexPage() {
12
+ * return (
13
+ * <div>
14
+ * <Head>
15
+ * <title>My page title</title>
16
+ * <meta name="viewport" content="initial-scale=1.0, width=device-width" />
17
+ * </Head>
18
+ * <p>Hello world!</p>
19
+ * </div>
20
+ * );
21
+ * }
22
+ *
23
+ * export default IndexPage;
24
+ * ```
25
+ *
26
+ */
27
+ declare function Head({ children }: {
28
+ children?: React.ReactNode;
29
+ }): JSX.Element;
30
+ declare namespace Head {
31
+ var rewind: () => HeadState | undefined;
32
+ }
33
+ export default Head;
@@ -0,0 +1,178 @@
1
+ // Based on https://github.com/zeit/next.js
2
+ // License: https://github.com/zeit/next.js/blob/977bf8d9ebd2845241b8689317f36e4e487f39d0/license.md
3
+ import * as React from 'react';
4
+ import withSideEffect from './side-effect';
5
+ import { HeadManagerContext } from './head-manager-context';
6
+ export const SHUVI_HEAD_ATTRIBUTE = 'data-shuvi-head';
7
+ const DOMAttributeNames = {
8
+ acceptCharset: 'accept-charset',
9
+ className: 'class',
10
+ htmlFor: 'for',
11
+ httpEquiv: 'http-equiv'
12
+ };
13
+ function reactElementToTag({ type, props }) {
14
+ const tag = {
15
+ tagName: type,
16
+ attrs: {}
17
+ };
18
+ for (const p in props) {
19
+ if (!props.hasOwnProperty(p))
20
+ continue;
21
+ if (p === 'children' || p === 'dangerouslySetInnerHTML')
22
+ continue;
23
+ // we don't render undefined props to the DOM
24
+ if (props[p] === undefined)
25
+ continue;
26
+ const attr = DOMAttributeNames[p] || p.toLowerCase();
27
+ tag.attrs[attr] = props[p];
28
+ }
29
+ const { children, dangerouslySetInnerHTML } = props;
30
+ if (dangerouslySetInnerHTML) {
31
+ tag.innerHTML = dangerouslySetInnerHTML.__html || '';
32
+ }
33
+ else if (children) {
34
+ tag.attrs.textContent =
35
+ typeof children === 'string' ? children : children.join('');
36
+ }
37
+ return tag;
38
+ }
39
+ function onlyReactElement(list, child) {
40
+ // React children can be "string" or "number" in this case we ignore them for backwards compat
41
+ if (typeof child === 'string' || typeof child === 'number') {
42
+ return list;
43
+ }
44
+ // Adds support for React.Fragment
45
+ if (child.type === React.Fragment) {
46
+ return list.concat(React.Children.toArray(child.props.children).reduce((fragmentList, fragmentChild) => {
47
+ if (typeof fragmentChild === 'string' ||
48
+ typeof fragmentChild === 'number') {
49
+ return fragmentList;
50
+ }
51
+ return fragmentList.concat(fragmentChild);
52
+ }, []));
53
+ }
54
+ return list.concat(child);
55
+ }
56
+ const METATYPES = ['name', 'httpEquiv', 'charSet', 'itemProp'];
57
+ /*
58
+ returns a function for filtering head child elements
59
+ which shouldn't be duplicated, like <title/>
60
+ Also adds support for deduplicated `key` properties
61
+ */
62
+ function unique() {
63
+ const keys = new Set();
64
+ const tags = new Set();
65
+ const metaTypes = new Set();
66
+ const metaCategories = {};
67
+ return (h) => {
68
+ let unique = true;
69
+ if (h.key && typeof h.key !== 'number' && h.key.indexOf('$') > 0) {
70
+ const key = h.key.slice(h.key.indexOf('$') + 1);
71
+ if (keys.has(key)) {
72
+ unique = false;
73
+ }
74
+ else {
75
+ keys.add(key);
76
+ }
77
+ }
78
+ // eslint-disable-next-line default-case
79
+ switch (h.type) {
80
+ case 'title':
81
+ case 'base':
82
+ if (tags.has(h.type)) {
83
+ unique = false;
84
+ }
85
+ else {
86
+ tags.add(h.type);
87
+ }
88
+ break;
89
+ case 'meta':
90
+ for (let i = 0, len = METATYPES.length; i < len; i++) {
91
+ const metatype = METATYPES[i];
92
+ if (!h.props.hasOwnProperty(metatype))
93
+ continue;
94
+ if (metatype === 'charSet') {
95
+ if (metaTypes.has(metatype)) {
96
+ unique = false;
97
+ }
98
+ else {
99
+ metaTypes.add(metatype);
100
+ }
101
+ }
102
+ else {
103
+ const category = h.props[metatype];
104
+ const categories = metaCategories[metatype] || new Set();
105
+ if (categories.has(category)) {
106
+ unique = false;
107
+ }
108
+ else {
109
+ categories.add(category);
110
+ metaCategories[metatype] = categories;
111
+ }
112
+ }
113
+ }
114
+ break;
115
+ }
116
+ return unique;
117
+ };
118
+ }
119
+ function onlyHeadElement(element) {
120
+ return typeof element.type === 'string';
121
+ }
122
+ /**
123
+ *
124
+ * @param headElement List of multiple <Head> instances
125
+ */
126
+ function reduceComponents(headElements) {
127
+ return headElements
128
+ .reduce((list, headElement) => {
129
+ const headElementChildren = React.Children.toArray(headElement.props.children);
130
+ return list.concat(headElementChildren);
131
+ }, [])
132
+ .reduce(onlyReactElement, [])
133
+ .filter(onlyHeadElement)
134
+ .reverse()
135
+ .filter(unique())
136
+ .reverse()
137
+ .map(e => {
138
+ const { type, props } = e;
139
+ const headElement = {
140
+ type,
141
+ props: Object.assign(Object.assign({}, props), { [SHUVI_HEAD_ATTRIBUTE]: 'true' })
142
+ };
143
+ return reactElementToTag(headElement);
144
+ });
145
+ }
146
+ const Effect = withSideEffect();
147
+ /**
148
+ * This component injects elements to `<head>` of your page.
149
+ * To avoid duplicated `tags` in `<head>` you can use the `key` property, which will make sure every tag is only rendered once.
150
+ *
151
+ * ```ts
152
+ * import { Head } from "@shuvi/runtime";
153
+ *
154
+ * function IndexPage() {
155
+ * return (
156
+ * <div>
157
+ * <Head>
158
+ * <title>My page title</title>
159
+ * <meta name="viewport" content="initial-scale=1.0, width=device-width" />
160
+ * </Head>
161
+ * <p>Hello world!</p>
162
+ * </div>
163
+ * );
164
+ * }
165
+ *
166
+ * export default IndexPage;
167
+ * ```
168
+ *
169
+ */
170
+ function Head({ children }) {
171
+ return (<HeadManagerContext.Consumer>
172
+ {updateHead => (<Effect reduceComponentsToState={reduceComponents} handleStateChange={updateHead}>
173
+ {children}
174
+ </Effect>)}
175
+ </HeadManagerContext.Consumer>);
176
+ }
177
+ Head.rewind = Effect.rewind;
178
+ export default Head;
@@ -0,0 +1,4 @@
1
+ import Head from './head';
2
+ import HeadManager from './head-manager';
3
+ export { HeadManagerContext } from './head-manager-context';
4
+ export { Head, HeadManager };
@@ -0,0 +1,4 @@
1
+ import Head from './head';
2
+ import HeadManager from './head-manager';
3
+ export { HeadManagerContext } from './head-manager-context';
4
+ export { Head, HeadManager };