@rspress/runtime 1.42.0 → 1.42.1-canary-20240227

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/dist/hooks.d.ts CHANGED
@@ -20,10 +20,5 @@ export declare function useLang(): string;
20
20
  export declare function useVersion(): string;
21
21
  export declare function useDark(): boolean;
22
22
  export declare function useI18n<T = Record<string, Record<string, string>>>(): (key: keyof T) => any;
23
- declare global {
24
- interface Document {
25
- startViewTransition: (callback: () => void) => any;
26
- }
27
- }
28
23
  export declare function useViewTransition(dom: ReactElement): ReactElement<any, string | import("react").JSXElementConstructor<any>>;
29
24
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspress/runtime",
3
- "version": "1.42.0",
3
+ "version": "1.42.1-canary-20240227",
4
4
  "description": "The Runtime of Rspress Documentation Framework",
5
5
  "bugs": "https://github.com/web-infra-dev/rspress/issues",
6
6
  "repository": {
@@ -24,6 +24,7 @@
24
24
  "default": "./dist/index.js"
25
25
  },
26
26
  "./server": {
27
+ "types": "./server.d.ts",
27
28
  "default": "./server.js"
28
29
  }
29
30
  },
@@ -31,24 +32,24 @@
31
32
  "types": "./dist/index.d.ts",
32
33
  "files": [
33
34
  "dist",
34
- "src",
35
- "server.js"
35
+ "server.js",
36
+ "server.d.ts"
36
37
  ],
37
38
  "dependencies": {
38
39
  "react": "^18.3.1",
39
40
  "react-dom": "^18.3.1",
40
41
  "react-helmet-async": "^1.3.0",
41
42
  "react-router-dom": "^6.29.0",
42
- "@rspress/shared": "1.42.0"
43
+ "@rspress/shared": "1.42.1-canary-20240227"
43
44
  },
44
45
  "devDependencies": {
45
- "@modern-js/tsconfig": "2.64.0",
46
46
  "@rsbuild/plugin-react": "~1.1.0",
47
- "@rslib/core": "0.4.1",
47
+ "@rslib/core": "0.5.2",
48
48
  "@types/jest": "~29.5.14",
49
49
  "@types/react": "^18.3.18",
50
50
  "@types/react-dom": "^18.3.5",
51
- "typescript": "^5.5.3"
51
+ "typescript": "^5.5.3",
52
+ "@rspress/config": "1.0.0"
52
53
  },
53
54
  "engines": {
54
55
  "node": ">=14.17.6"
@@ -58,7 +59,6 @@
58
59
  "provenance": true,
59
60
  "registry": "https://registry.npmjs.org/"
60
61
  },
61
- "jsnext:source": "./src/index.ts",
62
62
  "scripts": {
63
63
  "build": "rslib build",
64
64
  "dev": "rslib build -w",
package/server.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { StaticRouter } from 'react-router-dom/server';
package/src/Content.tsx DELETED
@@ -1,38 +0,0 @@
1
- import { type ReactElement, type ReactNode, Suspense, memo } from 'react';
2
- import { useLocation } from 'react-router-dom';
3
- import siteData from 'virtual-site-data';
4
- import { useViewTransition } from './hooks';
5
- import { pathnameToRouteService } from './route';
6
-
7
- function TransitionContentImpl(props: { el: ReactElement }) {
8
- let element = props.el;
9
- if (siteData?.themeConfig?.enableContentAnimation) {
10
- element = useViewTransition(props.el);
11
- }
12
- return element;
13
- }
14
-
15
- const TransitionContent = memo(
16
- TransitionContentImpl,
17
- (prevProps, nextProps) => prevProps.el === nextProps.el,
18
- );
19
-
20
- export const Content = ({ fallback = <></> }: { fallback?: ReactNode }) => {
21
- const { pathname } = useLocation();
22
- const matched = pathnameToRouteService(pathname);
23
- if (!matched) {
24
- return <div></div>;
25
- }
26
- const routesElement = matched.element;
27
-
28
- // React 17 Suspense SSR is not supported
29
- if (!process.env.__REACT_GTE_18__ && process.env.__SSR__) {
30
- return routesElement;
31
- }
32
-
33
- return (
34
- <Suspense fallback={fallback}>
35
- <TransitionContent el={routesElement} />
36
- </Suspense>
37
- );
38
- };
package/src/NoSSR.tsx DELETED
@@ -1,16 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
-
3
- export function NoSSR(props: { children: React.ReactNode }) {
4
- const { children } = props;
5
- const [isMounted, setIsMounted] = useState(false);
6
-
7
- useEffect(() => {
8
- setIsMounted(true);
9
- }, []);
10
-
11
- if (!isMounted) {
12
- return null;
13
- }
14
-
15
- return <>{children}</>;
16
- }
package/src/global.d.ts DELETED
@@ -1,20 +0,0 @@
1
- declare module 'virtual-routes' {
2
- export { Route } from 'node/route/RouteService';
3
-
4
- export const routes: Route[];
5
- }
6
-
7
- declare module 'virtual-routes-ssr' {
8
- export { Route } from 'node/route/RouteService';
9
-
10
- export const routes: Route[];
11
- }
12
-
13
- declare module 'virtual-site-data' {
14
- import { SiteData, DefaultThemeConfig } from '@rspress/shared';
15
-
16
- const data: SiteData<DefaultThemeConfig>;
17
- export default data;
18
- }
19
-
20
- declare module 'virtual-i18n-text';
package/src/hooks.ts DELETED
@@ -1,108 +0,0 @@
1
- import type { PageData } from '@rspress/shared';
2
- import {
3
- type ReactElement,
4
- createContext,
5
- useCallback,
6
- useContext,
7
- useLayoutEffect,
8
- useState,
9
- } from 'react';
10
- import { flushSync } from 'react-dom';
11
- import i18nTextData from 'virtual-i18n-text';
12
-
13
- // Type shim for window.__EDEN_PAGE_DATA__
14
- declare global {
15
- interface Window {
16
- __MODERN_PAGE_DATA__: any;
17
- }
18
- }
19
- interface IDataContext {
20
- data: PageData;
21
- setData?: (data: PageData) => void;
22
- }
23
-
24
- interface IThemeContext {
25
- theme: 'light' | 'dark';
26
- setTheme?: (theme: 'light' | 'dark') => void;
27
- }
28
-
29
- export const DataContext = createContext({} as IDataContext);
30
-
31
- export const ThemeContext = createContext({} as IThemeContext);
32
-
33
- export function usePageData(): PageData {
34
- const ctx = useContext(DataContext);
35
- return ctx.data;
36
- }
37
-
38
- export function useLang(): string {
39
- const ctx = useContext(DataContext);
40
- return ctx.data.page.lang || '';
41
- }
42
-
43
- export function useVersion(): string {
44
- const ctx = useContext(DataContext);
45
- return ctx.data.page.version || '';
46
- }
47
-
48
- export function useDark() {
49
- const ctx = useContext(ThemeContext);
50
- return ctx.theme === 'dark';
51
- }
52
-
53
- export function useI18n<T = Record<string, Record<string, string>>>() {
54
- const lang = useLang();
55
-
56
- return useCallback((key: keyof T) => i18nTextData[key][lang], [lang]);
57
- }
58
-
59
- declare global {
60
- interface Document {
61
- // @ts-ignore view-transition new API type is failed in tsc, but it works in vscode
62
- startViewTransition: (callback: () => void) => any;
63
- }
64
- }
65
-
66
- export function useViewTransition(dom: ReactElement) {
67
- /**
68
- * use a pseudo element to hold the actual JSX element so we can schedule the
69
- * update later in sync
70
- */
71
- const [element, setElement] = useState(dom);
72
-
73
- useLayoutEffect(() => {
74
- if (document.startViewTransition && element !== dom) {
75
- /**
76
- * the browser will take a screenshot here
77
- */
78
- document.startViewTransition(() => {
79
- /**
80
- * react will batch all the updates in callback and flush it sync
81
- */
82
- flushSync(() => {
83
- setElement(dom);
84
- });
85
- /**
86
- * react flushed the dom to browser
87
- * and the browser will start the animation
88
- */
89
- /**
90
- * dispatchEvent for several logic
91
- */
92
- window.dispatchEvent(new Event('RspressReloadContent'));
93
- });
94
- } else {
95
- flushSync(() => {
96
- setElement(dom);
97
- });
98
- /**
99
- * dispatchEvent for several logic
100
- */
101
- window.dispatchEvent(new Event('RspressReloadContent'));
102
- }
103
- }, [dom]);
104
- /**
105
- * take this element to the actual V-DOM tree
106
- */
107
- return element;
108
- }
package/src/index.ts DELETED
@@ -1,32 +0,0 @@
1
- export {
2
- DataContext,
3
- ThemeContext,
4
- useDark,
5
- useI18n,
6
- useLang,
7
- usePageData,
8
- useVersion,
9
- useViewTransition,
10
- } from './hooks';
11
- export { Content } from './Content';
12
- export {
13
- normalizeHrefInRuntime,
14
- normalizeImagePath,
15
- withBase,
16
- removeBase,
17
- addLeadingSlash,
18
- removeTrailingSlash,
19
- normalizeSlash,
20
- isProduction,
21
- isEqualPath,
22
- } from './utils';
23
- export {
24
- useLocation,
25
- useNavigate,
26
- matchRoutes,
27
- BrowserRouter,
28
- useSearchParams,
29
- } from 'react-router-dom';
30
- export { pathnameToRouteService } from './route';
31
- export { Helmet } from 'react-helmet-async';
32
- export { NoSSR } from './NoSSR';
package/src/route.test.ts DELETED
@@ -1,70 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { pathnameToRouteService } from './route';
3
-
4
- vi.mock('__VIRTUAL_ROUTES__', () => {
5
- const element = vi.fn();
6
- const routes = [
7
- {
8
- path: '/api/config',
9
- element,
10
- filePath: 'api/config.mdx',
11
- preload: async () => {},
12
- lang: '',
13
- version: '',
14
- },
15
- {
16
- path: '/api/config/',
17
- element,
18
- filePath: 'api/config/index.mdx',
19
- preload: async () => {},
20
- lang: '',
21
- version: '',
22
- },
23
- {
24
- path: '/',
25
- element,
26
- filePath: 'index.mdx',
27
- preload: async () => {},
28
- lang: '',
29
- version: '',
30
- },
31
- ];
32
- return { routes };
33
- });
34
-
35
- describe('pathnameToRouteService', () => {
36
- it('0. /api/config', () => {
37
- const pathname = '/api/config';
38
- // currently we do not support both /api/config.mdx and /api/config/index.mdx
39
- expect(pathnameToRouteService(pathname)?.path).toMatchInlineSnapshot(
40
- `"/api/config/"`,
41
- );
42
- });
43
-
44
- it('1. /api/config.html', () => {
45
- const pathname = '/api/config.html';
46
- expect(pathnameToRouteService(pathname)?.path).toMatchInlineSnapshot(
47
- `"/api/config/"`,
48
- );
49
- });
50
-
51
- it('2. /api/config/', () => {
52
- const pathname = '/api/config/';
53
- expect(pathnameToRouteService(pathname)?.path).toMatchInlineSnapshot(
54
- `"/api/config/"`,
55
- );
56
- });
57
-
58
- it('3. /api/config/index', () => {
59
- const pathname = '/api/config/index';
60
- expect(pathnameToRouteService(pathname)?.path).toMatchInlineSnapshot(
61
- `"/api/config/"`,
62
- );
63
- });
64
- it('4. /api/config/index.html', () => {
65
- const pathname = '/api/config/index.html';
66
- expect(pathnameToRouteService(pathname)?.path).toMatchInlineSnapshot(
67
- `"/api/config/"`,
68
- );
69
- });
70
- });
package/src/route.ts DELETED
@@ -1,32 +0,0 @@
1
- import type { Route } from '@rspress/shared';
2
- // @ts-expect-error __VIRTUAL_ROUTES__ will be determined at build time
3
- import { routes } from '__VIRTUAL_ROUTES__';
4
- import { matchRoutes } from 'react-router-dom';
5
-
6
- function normalizeRoutePath(routePath: string) {
7
- return decodeURIComponent(routePath)
8
- .replace(/\.html$/, '')
9
- .replace(/\/index$/, '/');
10
- }
11
-
12
- const cache = new Map<string, Route>();
13
- /**
14
- * this is a bridge of two core features Sidebar and RouteService
15
- * @param pathname useLocation().pathname
16
- * @returns
17
- */
18
- export function pathnameToRouteService(pathname: string): Route | undefined {
19
- const cacheItem = cache.get(pathname);
20
- if (cacheItem) {
21
- return cacheItem;
22
- }
23
- const matched = matchRoutes(
24
- routes as typeof import('virtual-routes')['routes'],
25
- normalizeRoutePath(pathname),
26
- );
27
- const route: Route | undefined = matched?.[0]?.route;
28
- if (route) {
29
- cache.set(pathname, route);
30
- }
31
- return route;
32
- }
package/src/utils.ts DELETED
@@ -1,55 +0,0 @@
1
- import {
2
- addLeadingSlash,
3
- isDataUrl,
4
- isExternalUrl,
5
- isProduction,
6
- normalizeHref,
7
- normalizeSlash,
8
- removeBase as rawRemoveBase,
9
- withBase as rawWithBase,
10
- removeHash,
11
- removeTrailingSlash,
12
- } from '@rspress/shared';
13
- import siteData from 'virtual-site-data';
14
-
15
- export function withBase(url = '/'): string {
16
- return rawWithBase(url, siteData.base);
17
- }
18
-
19
- export function removeBase(url: string): string {
20
- return rawRemoveBase(url, siteData.base);
21
- }
22
-
23
- export function isEqualPath(a: string, b: string) {
24
- return (
25
- withBase(normalizeHrefInRuntime(removeHash(a))) ===
26
- withBase(normalizeHrefInRuntime(removeHash(b)))
27
- );
28
- }
29
-
30
- export function normalizeHrefInRuntime(a: string) {
31
- const cleanUrls = Boolean(siteData?.route?.cleanUrls);
32
- return normalizeHref(a, cleanUrls);
33
- }
34
-
35
- export function normalizeImagePath(imagePath: string) {
36
- const isProd = isProduction();
37
- if (!isProd) {
38
- return imagePath;
39
- }
40
- if (isAbsoluteUrl(imagePath)) {
41
- return imagePath;
42
- }
43
- // only append base to internal non-relative urls
44
- if (!imagePath.startsWith('/')) {
45
- return imagePath;
46
- }
47
-
48
- return withBase(imagePath);
49
- }
50
-
51
- export function isAbsoluteUrl(path: string) {
52
- return isExternalUrl(path) || isDataUrl(path) || path.startsWith('//');
53
- }
54
-
55
- export { addLeadingSlash, removeTrailingSlash, normalizeSlash, isProduction };