feat(core): fail-safe global data fetching (#7083)

This commit is contained in:
Joshua Chen 2022-04-08 17:08:22 +08:00 committed by GitHub
parent 9145ae88cc
commit 171927342f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 51 additions and 26 deletions

View file

@ -11,11 +11,11 @@ import type {
GlobalPluginData,
GlobalVersion,
GlobalDoc,
GetActivePluginOptions,
ActivePlugin,
ActiveDocContext,
DocVersionSuggestions,
} from '@docusaurus/plugin-content-docs/client';
import type {UseDataOptions} from '@docusaurus/types';
// This code is not part of the api surface, not in ./theme on purpose
@ -25,7 +25,7 @@ import type {
export function getActivePlugin(
allPluginData: {[pluginId: string]: GlobalPluginData},
pathname: string,
options: GetActivePluginOptions = {},
options: UseDataOptions = {},
): ActivePlugin | undefined {
const activeEntry = Object.entries(allPluginData)
// Route sorting: '/android/foo' should match '/android' instead of '/'

View file

@ -6,7 +6,10 @@
*/
import {useLocation} from '@docusaurus/router';
import useGlobalData, {usePluginData} from '@docusaurus/useGlobalData';
import {
useAllPluginInstancesData,
usePluginData,
} from '@docusaurus/useGlobalData';
import {
getActivePlugin,
@ -21,25 +24,27 @@ import type {
ActivePlugin,
ActiveDocContext,
DocVersionSuggestions,
GetActivePluginOptions,
} from '@docusaurus/plugin-content-docs/client';
import type {UseDataOptions} from '@docusaurus/types';
// Important to use a constant object to avoid React useEffect executions etc.
// see https://github.com/facebook/docusaurus/issues/5089
const StableEmptyObject = {};
// Not using useAllPluginInstancesData() because in blog-only mode, docs hooks
// are still used by the theme. We need a fail-safe fallback when the docs
// plugin is not in use
// In blog-only mode, docs hooks are still used by the theme. We need a fail-
// safe fallback when the docs plugin is not in use
export const useAllDocsData = (): {[pluginId: string]: GlobalPluginData} =>
useGlobalData()['docusaurus-plugin-content-docs'] ?? StableEmptyObject;
useAllPluginInstancesData('docusaurus-plugin-content-docs') ??
StableEmptyObject;
export const useDocsData = (pluginId: string | undefined): GlobalPluginData =>
usePluginData('docusaurus-plugin-content-docs', pluginId) as GlobalPluginData;
usePluginData('docusaurus-plugin-content-docs', pluginId, {
failfast: true,
}) as GlobalPluginData;
// TODO this feature should be provided by docusaurus core
export const useActivePlugin = (
options: GetActivePluginOptions = {},
options: UseDataOptions = {},
): ActivePlugin | undefined => {
const data = useAllDocsData();
const {pathname} = useLocation();
@ -47,7 +52,7 @@ export const useActivePlugin = (
};
export const useActivePluginAndVersion = (
options: GetActivePluginOptions = {},
options: UseDataOptions = {},
):
| undefined
| {activePlugin: ActivePlugin; activeVersion: GlobalVersion | undefined} => {

View file

@ -612,6 +612,8 @@ declare module '@theme/DocPage/Layout/Main' {
// TODO until TS supports exports field... hope it's in 4.6
declare module '@docusaurus/plugin-content-docs/client' {
import type {UseDataOptions} from '@docusaurus/types';
export type ActivePlugin = {
pluginId: string;
pluginData: GlobalPluginData;
@ -655,15 +657,14 @@ declare module '@docusaurus/plugin-content-docs/client' {
// suggest the same doc, in latest version (if exist)
latestDocSuggestion?: GlobalDoc;
};
export type GetActivePluginOptions = {failfast?: boolean}; // use fail-fast option if you know for sure one plugin instance is active
export const useAllDocsData: () => {[pluginId: string]: GlobalPluginData};
export const useDocsData: (pluginId?: string) => GlobalPluginData;
export const useActivePlugin: (
options?: GetActivePluginOptions,
options?: UseDataOptions,
) => ActivePlugin | undefined;
export const useActivePluginAndVersion: (
options?: GetActivePluginOptions,
options?: UseDataOptions,
) =>
| {activePlugin: ActivePlugin; activeVersion: GlobalVersion | undefined}
| undefined;