@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 +0 -5
- package/package.json +8 -8
- package/server.d.ts +1 -0
- package/src/Content.tsx +0 -38
- package/src/NoSSR.tsx +0 -16
- package/src/global.d.ts +0 -20
- package/src/hooks.ts +0 -108
- package/src/index.ts +0 -32
- package/src/route.test.ts +0 -70
- package/src/route.ts +0 -32
- package/src/utils.ts +0 -55
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.
|
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
|
-
"
|
35
|
-
"server.
|
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.
|
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.
|
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 };
|