@docusaurus/core 0.0.0-4933 → 0.0.0-4940

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.
@@ -42,7 +42,9 @@ class PendingNavigation extends React.Component {
42
42
  previousLocation: this.previousLocation,
43
43
  location: nextLocation,
44
44
  });
45
- // Load data while the old screen remains.
45
+ // Load data while the old screen remains. Force preload instead of using
46
+ // `window.docusaurus`, because we want to avoid loading screen even when
47
+ // user is on saveData
46
48
  preload(nextLocation.pathname)
47
49
  .then(() => {
48
50
  this.routeUpdateCleanupCb?.();
@@ -16,7 +16,7 @@ declare global {
16
16
  }
17
17
  }
18
18
  declare const _default: Readonly<{
19
- prefetch: (routePath: string) => boolean;
20
- preload: (routePath: string) => boolean;
19
+ prefetch(routePath: string): false | Promise<void[]>;
20
+ preload(routePath: string): false | Promise<void[]>;
21
21
  }>;
22
22
  export default _default;
@@ -10,13 +10,13 @@ import routes from '@generated/routes';
10
10
  import prefetchHelper from './prefetch';
11
11
  import preloadHelper from './preload';
12
12
  import flat from './flat';
13
- const fetched = {};
14
- const loaded = {};
13
+ const fetched = new Set();
14
+ const loaded = new Set();
15
15
  // If user is on slow or constrained connection.
16
- const isSlowConnection = () => navigator.connection?.effectiveType.includes('2g') &&
16
+ const isSlowConnection = () => navigator.connection?.effectiveType.includes('2g') ||
17
17
  navigator.connection?.saveData;
18
- const canPrefetch = (routePath) => !isSlowConnection() && !loaded[routePath] && !fetched[routePath];
19
- const canPreload = (routePath) => !isSlowConnection() && !loaded[routePath];
18
+ const canPrefetch = (routePath) => !isSlowConnection() && !loaded.has(routePath) && !fetched.has(routePath);
19
+ const canPreload = (routePath) => !isSlowConnection() && !loaded.has(routePath);
20
20
  const getChunkNamesToLoad = (path) => Object.entries(routesChunkNames)
21
21
  .filter(
22
22
  // Remove the last part containing the route hash
@@ -25,38 +25,35 @@ const getChunkNamesToLoad = (path) => Object.entries(routesChunkNames)
25
25
  ([routeNameWithHash]) => routeNameWithHash.replace(/-[^-]+$/, '') === path)
26
26
  .flatMap(([, routeChunks]) => Object.values(flat(routeChunks)));
27
27
  const docusaurus = {
28
- prefetch: (routePath) => {
28
+ prefetch(routePath) {
29
29
  if (!canPrefetch(routePath)) {
30
30
  return false;
31
31
  }
32
- // Prevent future duplicate prefetch of routePath.
33
- fetched[routePath] = true;
32
+ fetched.add(routePath);
34
33
  // Find all webpack chunk names needed.
35
34
  const matches = matchRoutes(routes, routePath);
36
35
  const chunkNamesNeeded = matches.flatMap((match) => getChunkNamesToLoad(match.route.path));
37
36
  // Prefetch all webpack chunk assets file needed.
38
- chunkNamesNeeded.forEach((chunkName) => {
39
- // "__webpack_require__.gca" is a custom function provided by
40
- // ChunkAssetPlugin. Pass it the chunkName or chunkId you want to load and
41
- // it will return the URL for that chunk.
37
+ return Promise.all(chunkNamesNeeded.map((chunkName) => {
38
+ // "__webpack_require__.gca" is injected by ChunkAssetPlugin. Pass it
39
+ // the name of the chunk you want to load and it will return its URL.
42
40
  // eslint-disable-next-line camelcase
43
41
  const chunkAsset = __webpack_require__.gca(chunkName);
44
- // In some cases, webpack might decide to optimize further & hence the
45
- // chunk assets are merged to another chunk/previous chunk.
46
- // Hence, we can safely filter it out/don't need to load it.
42
+ // In some cases, webpack might decide to optimize further, leading to
43
+ // the chunk assets being merged to another chunk. In this case, we can
44
+ // safely filter it out and don't need to load it.
47
45
  if (chunkAsset && !/undefined/.test(chunkAsset)) {
48
- prefetchHelper(chunkAsset);
46
+ return prefetchHelper(chunkAsset);
49
47
  }
50
- });
51
- return true;
48
+ return Promise.resolve();
49
+ }));
52
50
  },
53
- preload: (routePath) => {
51
+ preload(routePath) {
54
52
  if (!canPreload(routePath)) {
55
53
  return false;
56
54
  }
57
- loaded[routePath] = true;
58
- preloadHelper(routePath);
59
- return true;
55
+ loaded.add(routePath);
56
+ return preloadHelper(routePath);
60
57
  },
61
58
  };
62
59
  // This object is directly mounted onto window, better freeze it
@@ -7,11 +7,5 @@
7
7
  /// <reference types="@docusaurus/module-type-aliases" />
8
8
  import React from 'react';
9
9
  import type { Props } from '@docusaurus/Link';
10
- import type docusaurus from '../docusaurus';
11
- declare global {
12
- interface Window {
13
- docusaurus: typeof docusaurus;
14
- }
15
- }
16
10
  declare const _default: React.ForwardRefExoticComponent<Pick<Props, "children" | "replace" | "slot" | "style" | "title" | "location" | "component" | "exact" | "sensitive" | "strict" | "type" | "key" | "id" | "lang" | "dir" | "rel" | "href" | "isNavLink" | "className" | "to" | "innerRef" | "download" | "hrefLang" | "media" | "ping" | "target" | "referrerPolicy" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "draggable" | "hidden" | "placeholder" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "activeClassName" | "activeStyle" | "isActive" | "data-noBrokenLinkCheck" | "autoAddBaseUrl"> & React.RefAttributes<HTMLAnchorElement>>;
17
11
  export default _default;
@@ -16,17 +16,17 @@ const isTree = (x) => typeof x === 'object' && !!x && Object.keys(x).length > 0;
16
16
  export default function flat(target) {
17
17
  const delimiter = '.';
18
18
  const output = {};
19
- function step(object, prefix) {
19
+ function dfs(object, prefix) {
20
20
  Object.entries(object).forEach(([key, value]) => {
21
21
  const newKey = prefix ? `${prefix}${delimiter}${key}` : key;
22
22
  if (isTree(value)) {
23
- step(value, newKey);
23
+ dfs(value, newKey);
24
24
  }
25
25
  else {
26
26
  output[newKey] = value;
27
27
  }
28
28
  });
29
29
  }
30
- step(target);
30
+ dfs(target);
31
31
  return output;
32
32
  }
@@ -22,8 +22,8 @@ function linkPrefetchStrategy(url) {
22
22
  const link = document.createElement('link');
23
23
  link.setAttribute('rel', 'prefetch');
24
24
  link.setAttribute('href', url);
25
- link.onload = resolve;
26
- link.onerror = reject;
25
+ link.onload = () => resolve();
26
+ link.onerror = () => reject();
27
27
  const parentElement = document.getElementsByTagName('head')[0] ??
28
28
  document.getElementsByName('script')[0]?.parentNode;
29
29
  parentElement?.appendChild(link);
@@ -48,18 +48,6 @@ function xhrPrefetchStrategy(url) {
48
48
  const supportedPrefetchStrategy = supports('prefetch')
49
49
  ? linkPrefetchStrategy
50
50
  : xhrPrefetchStrategy;
51
- const preFetched = {};
52
51
  export default function prefetch(url) {
53
- return new Promise((resolve) => {
54
- if (preFetched[url]) {
55
- resolve();
56
- return;
57
- }
58
- supportedPrefetchStrategy(url)
59
- .then(() => {
60
- resolve();
61
- preFetched[url] = true;
62
- })
63
- .catch(() => { }); // 404s are logged to the console anyway.
64
- });
52
+ return supportedPrefetchStrategy(url).catch(() => { }); // 404s are logged to the console anyway.
65
53
  }
@@ -88,7 +88,7 @@ async function buildLocale({ siteDir, locale, cliOptions, forceTerminate, isLast
88
88
  localizePath: cliOptions.locale ? false : undefined,
89
89
  });
90
90
  // Apply user webpack config.
91
- const { outDir, generatedFilesDir, plugins, siteConfig: { baseUrl, onBrokenLinks, staticDirectories }, routes, } = props;
91
+ const { outDir, generatedFilesDir, plugins, siteConfig: { baseUrl, onBrokenLinks, staticDirectories: staticDirectoriesOption, }, routes, } = props;
92
92
  const clientManifestPath = path_1.default.join(generatedFilesDir, 'client-manifest.json');
93
93
  let clientConfig = (0, webpack_merge_1.default)(await (0, client_1.default)(props, cliOptions.minify), {
94
94
  plugins: [
@@ -114,14 +114,23 @@ async function buildLocale({ siteDir, locale, cliOptions, forceTerminate, isLast
114
114
  headTags[staticPagePath] = tags;
115
115
  },
116
116
  });
117
+ // The staticDirectories option can contain empty directories, or non-existent
118
+ // directories (e.g. user deleted `static`). Instead of issuing an error, we
119
+ // just silently filter them out, because user could have never configured it
120
+ // in the first place (the default option should always "work").
121
+ const staticDirectories = (await Promise.all(staticDirectoriesOption.map(async (dir) => {
122
+ const staticDir = path_1.default.resolve(siteDir, dir);
123
+ if ((await fs_extra_1.default.pathExists(staticDir)) &&
124
+ (await fs_extra_1.default.readdir(staticDir)).length > 0) {
125
+ return staticDir;
126
+ }
127
+ return '';
128
+ }))).filter(Boolean);
117
129
  if (staticDirectories.length > 0) {
118
- await Promise.all(staticDirectories.map((dir) => fs_extra_1.default.ensureDir(dir)));
119
130
  serverConfig = (0, webpack_merge_1.default)(serverConfig, {
120
131
  plugins: [
121
132
  new copy_webpack_plugin_1.default({
122
- patterns: staticDirectories
123
- .map((dir) => path_1.default.resolve(siteDir, dir))
124
- .map((dir) => ({ from: dir, to: outDir })),
133
+ patterns: staticDirectories.map((dir) => ({ from: dir, to: outDir })),
125
134
  }),
126
135
  ],
127
136
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@docusaurus/core",
3
3
  "description": "Easy to Maintain Open Source Documentation Websites",
4
- "version": "0.0.0-4933",
4
+ "version": "0.0.0-4940",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -41,13 +41,13 @@
41
41
  "@babel/runtime": "^7.17.9",
42
42
  "@babel/runtime-corejs3": "^7.17.9",
43
43
  "@babel/traverse": "^7.17.10",
44
- "@docusaurus/cssnano-preset": "0.0.0-4933",
45
- "@docusaurus/logger": "0.0.0-4933",
46
- "@docusaurus/mdx-loader": "0.0.0-4933",
44
+ "@docusaurus/cssnano-preset": "0.0.0-4940",
45
+ "@docusaurus/logger": "0.0.0-4940",
46
+ "@docusaurus/mdx-loader": "0.0.0-4940",
47
47
  "@docusaurus/react-loadable": "5.5.2",
48
- "@docusaurus/utils": "0.0.0-4933",
49
- "@docusaurus/utils-common": "0.0.0-4933",
50
- "@docusaurus/utils-validation": "0.0.0-4933",
48
+ "@docusaurus/utils": "0.0.0-4940",
49
+ "@docusaurus/utils-common": "0.0.0-4940",
50
+ "@docusaurus/utils-validation": "0.0.0-4940",
51
51
  "@slorber/static-site-generator-webpack-plugin": "^4.0.4",
52
52
  "@svgr/webpack": "^6.2.1",
53
53
  "autoprefixer": "^10.4.5",
@@ -104,8 +104,8 @@
104
104
  "webpackbar": "^5.0.2"
105
105
  },
106
106
  "devDependencies": {
107
- "@docusaurus/module-type-aliases": "0.0.0-4933",
108
- "@docusaurus/types": "0.0.0-4933",
107
+ "@docusaurus/module-type-aliases": "0.0.0-4940",
108
+ "@docusaurus/types": "0.0.0-4940",
109
109
  "@types/detect-port": "^1.3.2",
110
110
  "@types/react-dom": "^18.0.3",
111
111
  "@types/react-router-config": "^5.0.6",
@@ -125,5 +125,5 @@
125
125
  "engines": {
126
126
  "node": ">=14"
127
127
  },
128
- "gitHead": "574df22fbe70bb8171267e47548a13921c083f8a"
128
+ "gitHead": "e2752f0bd8c9da9eff67162cb5f64dc30194cbf9"
129
129
  }