fumapress 0.5.0 → 0.5.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 (63) hide show
  1. package/css/generated.css +217 -3
  2. package/dist/adapters/mdx.d.ts +1 -1
  3. package/dist/client.d.ts +2 -23
  4. package/dist/client.js +3 -9
  5. package/dist/components/blog.js +4 -4
  6. package/dist/components/image.d.ts +30 -0
  7. package/dist/components/image.js +143 -0
  8. package/dist/components/link.d.ts +25 -0
  9. package/dist/components/link.js +18 -0
  10. package/dist/components/provider.d.ts +6 -0
  11. package/dist/components/provider.js +39 -0
  12. package/dist/config.d.ts +73 -30
  13. package/dist/config.js +14 -7
  14. package/dist/image.d.ts +2 -0
  15. package/dist/image.js +2 -0
  16. package/dist/index.d.ts +2 -2
  17. package/dist/layouts/blog.d.ts +1 -1
  18. package/dist/layouts/blog.index.js +3 -3
  19. package/dist/layouts/blog.js +3 -3
  20. package/dist/layouts/blog.tags.js +2 -2
  21. package/dist/layouts/docs.d.ts +2 -2
  22. package/dist/layouts/home.d.ts +1 -1
  23. package/dist/layouts/notebook.d.ts +2 -2
  24. package/dist/layouts/root.d.ts +5 -3
  25. package/dist/layouts/root.js +13 -16
  26. package/dist/layouts/switch.d.ts +2 -2
  27. package/dist/lib/pathname.js +14 -0
  28. package/dist/lib/shared.d.ts +10 -15
  29. package/dist/lib/shared.js +68 -33
  30. package/dist/lib/types.d.ts +30 -16
  31. package/dist/node_modules/.pnpm/http-cache-semantics@4.2.0/node_modules/http-cache-semantics/index.js +596 -0
  32. package/dist/plugins/blog.d.ts +3 -6
  33. package/dist/plugins/blog.js +6 -6
  34. package/dist/plugins/flexsearch.d.ts +1 -1
  35. package/dist/plugins/image/self-hosted.client.js +40 -0
  36. package/dist/plugins/image/self-hosted.d.ts +29 -0
  37. package/dist/plugins/image/self-hosted.js +30 -0
  38. package/dist/plugins/image/self-hosted.utils.js +270 -0
  39. package/dist/plugins/image/vercel.client.js +34 -0
  40. package/dist/plugins/image/vercel.d.ts +39 -0
  41. package/dist/plugins/image/vercel.enhancer.d.ts +10 -0
  42. package/dist/plugins/image/vercel.enhancer.js +16 -0
  43. package/dist/plugins/image/vercel.js +30 -0
  44. package/dist/plugins/image/vercel.utils.d.ts +10 -0
  45. package/dist/plugins/image/vercel.utils.js +30 -0
  46. package/dist/plugins/link-validation.d.ts +24 -0
  47. package/dist/plugins/link-validation.js +30 -0
  48. package/dist/plugins/llms.txt.d.ts +1 -1
  49. package/dist/plugins/llms.txt.js +2 -2
  50. package/dist/plugins/openapi.d.ts +2 -0
  51. package/dist/plugins/openapi.js +8 -1
  52. package/dist/plugins/orama-search.d.ts +1 -1
  53. package/dist/plugins/sitemap.d.ts +196 -0
  54. package/dist/plugins/sitemap.js +90 -0
  55. package/dist/plugins/takumi.d.ts +1 -1
  56. package/dist/plugins/takumi.js +3 -4
  57. package/dist/router/fs.js +1 -1
  58. package/dist/router/index.d.ts +17 -0
  59. package/dist/{router.js → router/index.js} +41 -26
  60. package/dist/vite.js +10 -10
  61. package/package.json +27 -9
  62. package/dist/lib/join-pathname.js +0 -9
  63. package/dist/router.d.ts +0 -15
@@ -0,0 +1,143 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { createContext, use, useMemo } from "react";
4
+ import ReactDOM from "react-dom";
5
+ import { useRouter } from "waku";
6
+ //#region src/components/image.tsx
7
+ function parseLength(v) {
8
+ if (typeof v !== "string") return v;
9
+ const parsed = parseInt(v, 10);
10
+ if (Number.isNaN(parsed)) throw new Error(`[Fumapress] <Image /> only accepts integer values of width/height, received: "${v}"`);
11
+ return parsed;
12
+ }
13
+ /**
14
+ * resolve src to a full pathname if relative
15
+ */
16
+ function normalizeSrc(src, basePathname) {
17
+ if (src.startsWith("http://") || src.startsWith("https://")) return src;
18
+ const base = new URL(basePathname, "http://localhost");
19
+ const resolved = new URL(src, base);
20
+ if (resolved.hostname !== base.hostname) throw new Error(`The src attribute "${src}" is not a valid relative path`);
21
+ return resolved.pathname;
22
+ }
23
+ const ImageContext = createContext(null);
24
+ function ImageProvider({ provider, children }) {
25
+ return /* @__PURE__ */ jsx(ImageContext, {
26
+ value: useMemo(() => ({ provider }), [provider]),
27
+ children
28
+ });
29
+ }
30
+ /** generate widths (ascending order) */
31
+ function getWidths(provider, width, sizes) {
32
+ if (sizes) {
33
+ const allSizes = provider.sizes ?? provider.deviceSizes;
34
+ const viewportWidthRe = /(^|\s)(1?\d?\d)vw/g;
35
+ const percentSizes = [];
36
+ for (let match; match = viewportWidthRe.exec(sizes);) percentSizes.push(parseInt(match[2]));
37
+ if (percentSizes.length !== 0) {
38
+ const minRatio = Math.min(...percentSizes) * .01;
39
+ const minSize = provider.deviceSizes[0] * minRatio;
40
+ const minIndex = allSizes.findLastIndex((s) => s < minSize);
41
+ return {
42
+ widths: minIndex === -1 ? allSizes : allSizes.slice(minIndex + 1),
43
+ kind: "w"
44
+ };
45
+ }
46
+ return {
47
+ widths: allSizes,
48
+ kind: "w"
49
+ };
50
+ }
51
+ if (typeof width !== "number") return {
52
+ widths: provider.deviceSizes,
53
+ kind: "w"
54
+ };
55
+ if (provider.sizes) {
56
+ const widths = /* @__PURE__ */ new Set();
57
+ const sizes = provider.sizes;
58
+ const defaultWidth = sizes.at(-1);
59
+ widths.add(sizes.find((p) => p >= width) ?? defaultWidth);
60
+ widths.add(sizes.find((p) => p >= width * 2) ?? defaultWidth);
61
+ return {
62
+ widths: Array.from(widths),
63
+ kind: "x"
64
+ };
65
+ }
66
+ return {
67
+ widths: [width, width * 2],
68
+ kind: "x"
69
+ };
70
+ }
71
+ function generateImageAttributes(provider, src, quality = provider.defaultQuality, width, sizes) {
72
+ const { widths, kind } = getWidths(provider, width, sizes);
73
+ return {
74
+ sizes: !sizes && kind === "w" ? "100vw" : sizes,
75
+ srcSet: widths.map((w, i) => `${provider.buildImageUrl({
76
+ src,
77
+ width: w,
78
+ quality
79
+ })} ${kind === "w" ? w : i + 1}${kind}`).join(", "),
80
+ src: provider.buildImageUrl({
81
+ src,
82
+ width: widths.at(-1),
83
+ quality
84
+ })
85
+ };
86
+ }
87
+ function Image({ src: _src, width: _width, height: _height, sizes, quality, unoptimized = false, preload = true, ...rest }) {
88
+ const ctx = use(ImageContext);
89
+ const pathname = useRouter().path;
90
+ const { src, width, height } = useMemo(() => {
91
+ if (typeof _src === "object") return {
92
+ src: normalizeSrc(_src.src, pathname),
93
+ width: parseLength(_width ?? _src.width),
94
+ height: parseLength(_height ?? _src.height)
95
+ };
96
+ return {
97
+ src: _src ? normalizeSrc(_src, pathname) : void 0,
98
+ width: parseLength(_width),
99
+ height: parseLength(_height)
100
+ };
101
+ }, [
102
+ _src,
103
+ _width,
104
+ _height,
105
+ pathname
106
+ ]);
107
+ if (src && ctx?.provider.canOptimize && !ctx.provider.canOptimize(src)) unoptimized = true;
108
+ if (!src || !ctx || unoptimized) return /* @__PURE__ */ jsx("img", {
109
+ ...rest,
110
+ width,
111
+ height,
112
+ sizes,
113
+ src
114
+ });
115
+ const { provider } = ctx;
116
+ provider.validate?.(src);
117
+ const generatedProps = generateImageAttributes(provider, src, quality, width, sizes);
118
+ let preloadElement;
119
+ if (preload) {
120
+ const preloadOptions = {
121
+ as: "image",
122
+ imageSrcSet: generatedProps.srcSet,
123
+ imageSizes: generatedProps.sizes,
124
+ crossOrigin: rest.crossOrigin,
125
+ referrerPolicy: rest.referrerPolicy,
126
+ fetchPriority: rest.fetchPriority
127
+ };
128
+ if (ReactDOM.preload) ReactDOM.preload(generatedProps.src, preloadOptions);
129
+ else preloadElement = /* @__PURE__ */ jsx("link", {
130
+ rel: "preload",
131
+ href: generatedProps.srcSet ? void 0 : generatedProps.src,
132
+ ...preloadOptions
133
+ }, "press-img-" + generatedProps.src + generatedProps.srcSet + generatedProps.sizes);
134
+ }
135
+ return /* @__PURE__ */ jsxs(Fragment, { children: [preloadElement, /* @__PURE__ */ jsx("img", {
136
+ ...rest,
137
+ width,
138
+ height,
139
+ ...generatedProps
140
+ })] });
141
+ }
142
+ //#endregion
143
+ export { Image, ImageProvider };
@@ -0,0 +1,25 @@
1
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
2
+ import { ComponentProps, ReactNode, TransitionFunction } from "react";
3
+
4
+ //#region src/components/link.d.ts
5
+ interface LinkProps extends ComponentProps<"a"> {
6
+ /**
7
+ * indicates if the link should scroll or not on navigation
8
+ * - `true`: always scroll
9
+ * - `false`: never scroll
10
+ * - `undefined`: scroll on path/hash change (not on query-only change)
11
+ */
12
+ scroll?: boolean;
13
+ unstable_pending?: ReactNode;
14
+ unstable_notPending?: ReactNode;
15
+ unstable_prefetchOnEnter?: boolean;
16
+ unstable_prefetchOnView?: boolean;
17
+ unstable_startTransition?: ((fn: TransitionFunction) => void) | undefined;
18
+ }
19
+ declare function Link({
20
+ href,
21
+ children,
22
+ ...props
23
+ }: LinkProps): _$react_jsx_runtime0.JSX.Element;
24
+ //#endregion
25
+ export { Link, LinkProps };
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useRouter as useRouter$1 } from "../client.js";
3
+ import { Link } from "waku/router/client";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/link.tsx
6
+ function Link$1({ href = "#", children, ...props }) {
7
+ if (typeof global !== "undefined" && global.LINK_SSG_CONTEXT) global.LINK_SSG_CONTEXT.links.push({
8
+ href,
9
+ fromPathname: useRouter$1().path
10
+ });
11
+ return /* @__PURE__ */ jsx(Link, {
12
+ to: href,
13
+ ...props,
14
+ children
15
+ });
16
+ }
17
+ //#endregion
18
+ export { Link$1 as Link };
@@ -0,0 +1,6 @@
1
+ import { RootProviderProps } from "fumadocs-ui/provider/base";
2
+
3
+ //#region src/components/provider.d.ts
4
+ type PressProviderProps = RootProviderProps;
5
+ //#endregion
6
+ export { PressProviderProps };
@@ -0,0 +1,39 @@
1
+ "use client";
2
+ import { Link } from "./link.js";
3
+ import { useRouter } from "../client.js";
4
+ import { Image } from "./image.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import { useMemo } from "react";
7
+ import { FrameworkProvider } from "fumadocs-core/framework";
8
+ import { RootProvider } from "fumadocs-ui/provider/base";
9
+ //#region src/components/provider.tsx
10
+ const framework = {
11
+ useParams() {
12
+ console.warn("[Fumadocs] useParams() is not supported on Fumapress");
13
+ return useMemo(() => ({}), []);
14
+ },
15
+ usePathname() {
16
+ return useRouter().path;
17
+ },
18
+ useRouter() {
19
+ const router = useRouter();
20
+ return useMemo(() => ({
21
+ push: router.push.bind(router),
22
+ refresh: router.reload.bind(router)
23
+ }), [router]);
24
+ },
25
+ Image: ({ priority, ...props }) => /* @__PURE__ */ jsx(Image, {
26
+ fetchPriority: priority ? "high" : void 0,
27
+ loading: priority ? "eager" : void 0,
28
+ ...props
29
+ }),
30
+ Link
31
+ };
32
+ function PressProvider(props) {
33
+ return /* @__PURE__ */ jsx(FrameworkProvider, {
34
+ ...framework,
35
+ children: /* @__PURE__ */ jsx(RootProvider, { ...props })
36
+ });
37
+ }
38
+ //#endregion
39
+ export { PressProvider };
package/dist/config.d.ts CHANGED
@@ -1,35 +1,71 @@
1
1
  import { AppContext } from "./lib/shared.js";
2
- import { Adapter, Awaitable, ServerPluginOption } from "./lib/types.js";
3
- import { LoaderConfig, LoaderOutput } from "fumadocs-core/source";
2
+ import { Adapter, Awaitable, PressLoaderOptions, ServerPluginOption } from "./lib/types.js";
4
3
  import { FC, ReactNode } from "react";
4
+ import { LoaderConfig, LoaderOutput, Meta, Page, SourceUnion, _Internal } from "fumadocs-core/source";
5
5
  import { I18nConfig, SingularTranslationsAPI, TranslationsAPI } from "fumadocs-core/i18n";
6
6
  import { Translations } from "fumadocs-ui/i18n";
7
7
  import { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
8
8
 
9
9
  //#region src/config.d.ts
10
10
  interface ConfigContext {
11
- loaderConfig: LoaderConfig;
12
- lang: string;
11
+ page: Page;
12
+ meta: Meta;
13
+ i18n: I18nConfig | undefined;
14
+ /** source names in multi-source setup */
15
+ source: string | undefined;
13
16
  }
14
17
  type BuildMode = "static" | "dynamic" | "default";
15
- interface Config<C extends ConfigContext = ConfigContext> {
18
+ interface BaseConfig<C extends ConfigContext> {
16
19
  /**
17
20
  * - `static`: always prefer static, including search etc.
18
21
  * - `dynamic`: always prefer dynamic.
19
22
  * - `default`: only certain parts like search routes are dynamic.
20
23
  */
21
24
  mode?: BuildMode;
22
- /** the default content loader */
23
- loader?: LoaderOutput<C["loaderConfig"]> | (() => Awaitable<LoaderOutput<C["loaderConfig"]>>);
24
25
  site?: SiteConfig;
25
- /** this is optional if you have defined `translations` */
26
- i18n?: I18nConfig<C["lang"]>;
27
- translations?: TranslationsAPI<C["lang"], {
26
+ translations?: (C["i18n"] extends I18nConfig<infer Lang> ? TranslationsAPI<Lang, {
28
27
  ui: Translations;
29
- }> | SingularTranslationsAPI<{
28
+ }> : never) | SingularTranslationsAPI<{
30
29
  ui: Translations;
31
30
  }>;
32
- meta?: MetaConfig<NoInfer<C>>;
31
+ meta?: {
32
+ /** render meta tags for any pages */root?: (this: AppContext<C>) => ReactNode; /** render meta tags for page */
33
+ page?: (this: AppContext<C>, page: C["page"]) => ReactNode;
34
+ };
35
+ }
36
+ interface ConfigWithLoader<L extends LoaderConfig = LoaderConfig> extends BaseConfig<{
37
+ meta: NoInfer<L>["meta"];
38
+ page: NoInfer<L>["page"];
39
+ i18n: NoInfer<L>["i18n"];
40
+ source: undefined;
41
+ }> {
42
+ /**
43
+ * The content loader.
44
+ *
45
+ * @deprecated Pass content sources directly to `content` instead.
46
+ */
47
+ loader?: LoaderOutput<L>;
48
+ }
49
+ interface ConfigWithContent<I extends _Internal.AnyInput = _Internal.AnyInput, I18n extends I18nConfig | undefined = I18nConfig | undefined> extends BaseConfig<{
50
+ i18n: I18n;
51
+ meta: _Internal.GenerateMeta<NoInfer<I>>;
52
+ page: _Internal.GeneratePage<NoInfer<I>>;
53
+ source: I extends Record<infer K, SourceUnion> ? K : undefined;
54
+ }> {
55
+ /** The content sources */
56
+ content: I;
57
+ /** i18n config for core, optional when `translations` is specified */
58
+ i18n?: I18n;
59
+ /** Options for Fumadocs Loader API */
60
+ loaderOptions?: Omit<PressLoaderOptions<_Internal.GenerateStorage<I>, I18n>, "baseUrl" | "i18n"> & {
61
+ /**
62
+ * Always revalidate all dynamic content sources in `content` (on each request).
63
+ * By default, you can revalidate manually with `getPressContext<Ctx>().revalidateLoader(...)`.
64
+ *
65
+ * @default false
66
+ */
67
+ alwaysRevalidate?: boolean;
68
+ };
33
69
  }
34
70
  interface Layouts<C extends ConfigContext = ConfigContext> {
35
71
  root: FC<{
@@ -41,7 +77,7 @@ interface Layouts<C extends ConfigContext = ConfigContext> {
41
77
  page: FC<{
42
78
  lang?: string;
43
79
  slugs: string[];
44
- page: C["loaderConfig"]["page"];
80
+ page: C["page"];
45
81
  }> & {
46
82
  $ctx?: C;
47
83
  };
@@ -57,12 +93,6 @@ interface Layouts<C extends ConfigContext = ConfigContext> {
57
93
  lang: string | undefined;
58
94
  }) => Awaitable<Omit<BaseLayoutProps, "children">>;
59
95
  }
60
- interface MetaConfig<C extends ConfigContext = ConfigContext> {
61
- /** render meta tags for any pages */
62
- root?: (this: AppContext<C>) => ReactNode;
63
- /** render meta tags for page */
64
- page?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => ReactNode;
65
- }
66
96
  interface SiteConfig {
67
97
  /** full URL of app, used for metadata generation*/
68
98
  baseUrl?: string;
@@ -74,23 +104,36 @@ interface SiteConfig {
74
104
  rootDir?: string;
75
105
  };
76
106
  }
77
- interface ConfigBuilder<C extends ConfigContext> extends Config<C> {
107
+ interface ConfigBuilder<C extends ConfigContext = ConfigContext> {
78
108
  /** for type inference only, always `undefined` */
79
109
  $context: C;
80
- getPlugins: () => ServerPluginOption<C>[];
81
- getLayouts: () => Partial<Layouts<C>>;
82
- getAdapters: () => Adapter<C>[];
110
+ get: () => (ConfigWithLoader | ConfigWithContent) & {
111
+ plugins: ServerPluginOption[];
112
+ layouts: Partial<Layouts>;
113
+ adapters: Adapter[];
114
+ };
115
+ /** alias for `usePlugins()` */
116
+ plugins: (...plugins: ServerPluginOption<C>[]) => ConfigBuilder<C>;
117
+ /** alias for `useAdapters()` */
118
+ adapters: (...adapters: Adapter<C>[]) => ConfigBuilder<C>;
119
+ /** alias for `useLayouts()` */
120
+ layouts: (layouts: Partial<Layouts<C>>) => ConfigBuilder<C>;
83
121
  usePlugins: (...plugins: ServerPluginOption<C>[]) => ConfigBuilder<C>;
84
122
  useLayouts: (layouts: Partial<Layouts<C>>) => ConfigBuilder<C>;
85
123
  /** Add adapter for content sources */
86
124
  useAdapters: (...adapters: Adapter<C>[]) => ConfigBuilder<C>;
87
125
  }
88
- declare function defineConfig<C extends LoaderConfig, L extends string = string>(config: Config<{
89
- loaderConfig: C;
90
- lang: L;
91
- }>): ConfigBuilder<{
92
- loaderConfig: C;
93
- lang: L;
126
+ declare function defineConfig<I extends _Internal.AnyInput, I18n extends I18nConfig | undefined = undefined>(config: ConfigWithContent<I, I18n>): ConfigBuilder<{
127
+ meta: _Internal.GenerateMeta<I>;
128
+ page: _Internal.GeneratePage<I>;
129
+ source: I extends Record<infer K, SourceUnion> ? K : undefined;
130
+ i18n: I18n;
131
+ }>;
132
+ declare function defineConfig<L extends LoaderConfig>(config?: ConfigWithLoader<L>): ConfigBuilder<{
133
+ i18n: L["i18n"];
134
+ page: L["page"];
135
+ meta: L["meta"];
136
+ source: undefined;
94
137
  }>;
95
138
  //#endregion
96
- export { BuildMode, Config, ConfigBuilder, ConfigContext, Layouts, MetaConfig, SiteConfig, defineConfig };
139
+ export { BaseConfig, BuildMode, ConfigBuilder, ConfigContext, Layouts, SiteConfig, defineConfig };
package/dist/config.js CHANGED
@@ -4,16 +4,23 @@ function defineConfig(config) {
4
4
  const layouts = {};
5
5
  const adapters = [];
6
6
  return {
7
- ...config,
8
7
  $context: void 0,
9
- getPlugins() {
10
- return plugins;
8
+ get() {
9
+ return {
10
+ ...config,
11
+ plugins,
12
+ layouts,
13
+ adapters
14
+ };
11
15
  },
12
- getAdapters() {
13
- return adapters;
16
+ plugins(...plugins) {
17
+ return this.usePlugins(...plugins);
14
18
  },
15
- getLayouts() {
16
- return layouts;
19
+ adapters(...adapters) {
20
+ return this.useAdapters(...adapters);
21
+ },
22
+ layouts(layouts) {
23
+ return this.useLayouts(layouts);
17
24
  },
18
25
  useAdapters(...values) {
19
26
  adapters.push(...values);
@@ -0,0 +1,2 @@
1
+ import { Image, ImageProps, StaticImageData } from "./components/image.js";
2
+ export { Image, type ImageProps, type StaticImageData };
package/dist/image.js ADDED
@@ -0,0 +1,2 @@
1
+ import { Image } from "./components/image.js";
2
+ export { Image };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { AppContext, getPressContext } from "./lib/shared.js";
2
- import { BuildMode, Config, ConfigBuilder, ConfigContext, Layouts, MetaConfig, SiteConfig, defineConfig } from "./config.js";
2
+ import { BuildMode, ConfigBuilder, ConfigContext, Layouts, SiteConfig, defineConfig } from "./config.js";
3
3
  import { Adapter, AppContextData, RouteConfig, RouteFns, ServerPlugin, ServerPluginOption } from "./lib/types.js";
4
- export { type Adapter, type AppContext, type AppContextData, BuildMode, Config, ConfigBuilder, ConfigContext, Layouts, MetaConfig, type RouteConfig, type RouteFns, type ServerPlugin, type ServerPluginOption, SiteConfig, defineConfig, getPressContext };
4
+ export { type Adapter, type AppContext, type AppContextData, type BuildMode, type ConfigBuilder, type ConfigContext, type Layouts, type RouteConfig, type RouteFns, type ServerPlugin, type ServerPluginOption, type SiteConfig, defineConfig, getPressContext };
@@ -15,7 +15,7 @@ interface BlogLayoutPageRenderData {
15
15
  body: ReactNode;
16
16
  }
17
17
  interface BlogLayoutPageOptions<C extends ConfigContext = ConfigContext> {
18
- render?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<Partial<BlogLayoutPageRenderData>>;
18
+ render?: (this: AppContext<C>, page: C["page"]) => Awaitable<Partial<BlogLayoutPageRenderData>>;
19
19
  }
20
20
  declare function createBlogLayoutPage<C extends ConfigContext = ConfigContext>(options?: BlogLayoutPageOptions<C>): BlogLayoutPage<C>;
21
21
  //#endregion
@@ -1,11 +1,11 @@
1
+ import { Link } from "../components/link.js";
1
2
  import { getPressContext } from "../lib/shared.js";
2
3
  import { cn } from "../lib/cn.js";
3
4
  import { I18nLabel } from "../components/i18n.js";
4
- import { joinPathname } from "../lib/join-pathname.js";
5
+ import { joinPathname } from "../lib/pathname.js";
5
6
  import { getBlogContext } from "../plugins/blog.js";
6
7
  import { OrderedBlogGrid } from "../components/blog.js";
7
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
- import { Link } from "waku";
9
9
  import { ListIcon } from "lucide-react";
10
10
  import { buttonVariants } from "fumadocs-ui/components/ui/button";
11
11
  //#region src/layouts/blog.index.tsx
@@ -26,7 +26,7 @@ function createBlogIndexPage({ heading, description } = {}) {
26
26
  children: description
27
27
  }),
28
28
  tagsPath !== false && /* @__PURE__ */ jsxs(Link, {
29
- to: lang ? joinPathname(lang, tagsPath) : tagsPath,
29
+ href: lang ? joinPathname(lang, tagsPath) : tagsPath,
30
30
  className: cn(buttonVariants({ variant: "primary" }), "gap-2"),
31
31
  children: [/* @__PURE__ */ jsx(ListIcon, { className: "size-4" }), /* @__PURE__ */ jsx(I18nLabel, { label: "allTags" })]
32
32
  })
@@ -1,12 +1,12 @@
1
+ import { Link } from "../components/link.js";
1
2
  import { getCreationDate, getPressContext, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
2
3
  import { BlogPanel, BlogProvider } from "../components/blog-panel.js";
3
4
  import { getTags } from "../lib/shared/blog.js";
4
- import { joinPathname } from "../lib/join-pathname.js";
5
+ import { joinPathname } from "../lib/pathname.js";
5
6
  import { createHomeLayout } from "./home.js";
6
7
  import { getBlogContext } from "../plugins/blog.js";
7
8
  import { LinkToHome } from "../components/blog.js";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
- import { Link } from "waku";
10
10
  import { TagIcon } from "lucide-react";
11
11
  //#region src/layouts/blog.tsx
12
12
  /** You can use `createHomeLayout()` directly, this is only a wrapper */
@@ -48,7 +48,7 @@ function createBlogLayoutPage(options = {}) {
48
48
  className: "flex flex-row items-center gap-2 flex-wrap w-full max-w-[900px] text-sm text-fd-primary-foreground font-mono",
49
49
  children: [/* @__PURE__ */ jsx(TagIcon, { className: "size-4 text-fd-muted-foreground" }), tags.map((t) => {
50
50
  if (tagsPath !== false) return /* @__PURE__ */ jsx(Link, {
51
- to: joinPathname(lang ?? "", tagsPath, t),
51
+ href: joinPathname(lang ?? "", tagsPath, t),
52
52
  className: "px-1.5 py-0.5 rounded-lg bg-fd-primary",
53
53
  children: t
54
54
  }, t);
@@ -1,10 +1,10 @@
1
+ import { Link } from "../components/link.js";
1
2
  import { getPressContext } from "../lib/shared.js";
2
3
  import { I18nLabel } from "../components/i18n.js";
3
4
  import { getTags, groupTags } from "../lib/shared/blog.js";
4
5
  import { getBlogContext } from "../plugins/blog.js";
5
6
  import { LinkToHome, OrderedBlogGrid } from "../components/blog.js";
6
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
- import { Link } from "waku";
8
8
  import { NewspaperIcon, TagIcon } from "lucide-react";
9
9
  //#region src/layouts/blog.tags.tsx
10
10
  function createBlogTagsPage({ heading, description } = {}) {
@@ -34,7 +34,7 @@ function createBlogTagsPage({ heading, description } = {}) {
34
34
  }), /* @__PURE__ */ jsx("div", {
35
35
  className: "grid grid-cols-2 sm:grid-cols-3 gap-2 mt-4 md:grid-cols-4 xl:grid-cols-6",
36
36
  children: Array.from(grouped.entries()).sort((a, b) => b[1] - a[1]).map(([tag, count]) => /* @__PURE__ */ jsxs(Link, {
37
- to: `/blog/tags/${tag}`,
37
+ href: `/blog/tags/${tag}`,
38
38
  className: "flex flex-row items-center gap-2 bg-fd-card text-fd-card-foreground border font-mono rounded-lg px-2 py-1 transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground",
39
39
  children: [
40
40
  /* @__PURE__ */ jsx(TagIcon, { className: "size-3.5 text-fd-muted-foreground" }),
@@ -1,8 +1,8 @@
1
1
  import { AppContext, TransformChildren } from "../lib/shared.js";
2
2
  import { ConfigContext, Layouts } from "../config.js";
3
3
  import { Awaitable } from "../lib/types.js";
4
- import { Page } from "fumadocs-core/source";
5
4
  import { ReactNode } from "react";
5
+ import { Page } from "fumadocs-core/source";
6
6
  import { DocsLayoutProps } from "fumadocs-ui/layouts/docs";
7
7
  import { DocsPageProps } from "fumadocs-ui/layouts/docs/page";
8
8
 
@@ -13,7 +13,7 @@ interface DocsLayoutOptions<C extends ConfigContext = ConfigContext> {
13
13
  };
14
14
  render?: (this: AppContext<C> & {
15
15
  lang?: string;
16
- }, page: C["loaderConfig"]["page"]) => Awaitable<{
16
+ }, page: C["page"]) => Awaitable<{
17
17
  markdownUrl?: string;
18
18
  lastModified?: Date | null;
19
19
  body?: ReactNode;
@@ -15,7 +15,7 @@ type LayoutComponent<C extends ConfigContext> = FC<{
15
15
  interface HomeLayoutPageOptions<C extends ConfigContext = ConfigContext> {
16
16
  /** swap the outer layout of page content */
17
17
  layout?: LayoutComponent<C>;
18
- render?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<{
18
+ render?: (this: AppContext<C>, page: C["page"]) => Awaitable<{
19
19
  body?: ReactNode;
20
20
  layoutProps?: TransformChildren<HomeLayoutProps>;
21
21
  }>;
@@ -1,8 +1,8 @@
1
1
  import { AppContext, TransformChildren } from "../lib/shared.js";
2
2
  import { ConfigContext, Layouts } from "../config.js";
3
3
  import { Awaitable } from "../lib/types.js";
4
- import { Page } from "fumadocs-core/source";
5
4
  import { ReactNode } from "react";
5
+ import { Page } from "fumadocs-core/source";
6
6
  import { DocsLayoutProps } from "fumadocs-ui/layouts/notebook";
7
7
  import { DocsPageProps } from "fumadocs-ui/layouts/notebook/page";
8
8
 
@@ -13,7 +13,7 @@ interface NotebookLayoutOptions<C extends ConfigContext = ConfigContext> {
13
13
  };
14
14
  render?: (this: AppContext<C> & {
15
15
  lang?: string;
16
- }, page: C["loaderConfig"]["page"]) => Awaitable<{
16
+ }, page: C["page"]) => Awaitable<{
17
17
  markdownUrl?: string;
18
18
  lastModified?: Date | null;
19
19
  body?: ReactNode;
@@ -1,10 +1,12 @@
1
1
  import { ConfigContext, Layouts } from "../config.js";
2
- import { RootProviderProps } from "fumadocs-ui/provider/waku";
2
+ import { PressProviderProps } from "../components/provider.js";
3
+ import { Awaitable } from "../lib/types.js";
3
4
 
4
5
  //#region src/layouts/root.d.ts
5
6
  interface RootLayoutOptions {
6
- providerProps?: Omit<RootProviderProps, "children">;
7
+ providerProps?: Omit<PressProviderProps, "children">;
7
8
  }
9
+ type RootLayoutContextData = ((props: PressProviderProps) => Awaitable<PressProviderProps>)[];
8
10
  declare function createRootLayout<C extends ConfigContext = ConfigContext>(options?: RootLayoutOptions): Layouts<C>["root"];
9
11
  //#endregion
10
- export { RootLayoutOptions, createRootLayout };
12
+ export { RootLayoutContextData, RootLayoutOptions, createRootLayout };
@@ -1,24 +1,24 @@
1
1
  import { getPressContext, renderRootMeta } from "../lib/shared.js";
2
+ import { PressProvider } from "../components/provider.js";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { RootProvider } from "fumadocs-ui/provider/waku";
4
4
  import { i18nProvider } from "fumadocs-ui/i18n";
5
+ import stylesInline from "virtual:root.css?inline";
6
+ import stylesHref from "virtual:root.css?url";
5
7
  //#region src/layouts/root.tsx
6
8
  let styleTag;
7
- if (import.meta.env.DEV) {
8
- const { default: styles } = await import("virtual:root.css?inline");
9
- styleTag = /* @__PURE__ */ jsx("style", { children: styles });
10
- } else {
11
- const { default: cssUrl } = await import("virtual:root.css?url");
12
- styleTag = /* @__PURE__ */ jsx("link", {
13
- rel: "stylesheet",
14
- href: cssUrl
15
- });
16
- }
9
+ if (import.meta.env.DEV) styleTag = /* @__PURE__ */ jsx("style", { children: stylesInline });
10
+ else styleTag = /* @__PURE__ */ jsx("link", {
11
+ rel: "stylesheet",
12
+ href: stylesHref
13
+ });
17
14
  function createRootLayout(options) {
18
15
  return async function({ lang, children }) {
19
16
  const ctx = getPressContext();
20
17
  const hooks = ctx.data["core:provider"];
21
- let providerProps = { ...options?.providerProps };
18
+ let providerProps = {
19
+ ...options?.providerProps,
20
+ children
21
+ };
22
22
  if (ctx.translationsConfig && "config" in ctx.translationsConfig) providerProps.i18n ??= i18nProvider(ctx.translationsConfig, lang);
23
23
  else if (ctx.translationsConfig) providerProps.i18n ??= i18nProvider(ctx.translationsConfig);
24
24
  if (hooks) for (const hook of hooks) providerProps = await hook(providerProps);
@@ -28,10 +28,7 @@ function createRootLayout(options) {
28
28
  children: [/* @__PURE__ */ jsxs("head", { children: [styleTag, renderRootMeta(ctx)] }), /* @__PURE__ */ jsx("body", {
29
29
  "data-version": "1.0",
30
30
  className: "flex flex-col min-h-screen",
31
- children: /* @__PURE__ */ jsx(RootProvider, {
32
- ...providerProps,
33
- children
34
- })
31
+ children: /* @__PURE__ */ jsx(PressProvider, { ...providerProps })
35
32
  })]
36
33
  });
37
34
  };
@@ -3,9 +3,9 @@ import { ConfigContext, Layouts } from "../config.js";
3
3
  import { Page } from "fumadocs-core/source";
4
4
 
5
5
  //#region src/layouts/switch.d.ts
6
- declare function createLayoutSwitchAuto<C extends ConfigContext = ConfigContext>(layouts: Record<C["loaderConfig"]["page"] extends Page<infer Type extends string> ? Type : never, Layouts<C>["page"]>): Layouts<C>["page"];
6
+ declare function createLayoutSwitchAuto<C extends ConfigContext = ConfigContext>(layouts: Record<C["page"] extends Page<infer Type extends string> ? Type : never, Layouts<C>["page"]>): Layouts<C>["page"];
7
7
  declare function createLayoutSwitch<const T extends string, C extends ConfigContext = ConfigContext>(/** detect layout from page */
8
8
 
9
- detector: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => T | undefined, layouts: Record<NoInfer<T>, Layouts<C>["page"]>): Layouts<C>["page"];
9
+ detector: (this: AppContext<C>, page: C["page"]) => T | undefined, layouts: Record<NoInfer<T>, Layouts<C>["page"]>): Layouts<C>["page"];
10
10
  //#endregion
11
11
  export { createLayoutSwitch, createLayoutSwitchAuto };