blume 1.6.5 → 1.7.0
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/CHANGELOG.md +39 -0
- package/bin/blume.mjs +3 -2
- package/dist/cli/chunk-0qhq7b8q.js +111 -0
- package/dist/cli/chunk-0qhq7b8q.js.map +11 -0
- package/dist/cli/chunk-18tjv4f7.js +96 -0
- package/dist/cli/chunk-18tjv4f7.js.map +10 -0
- package/dist/cli/chunk-27gtm2ym.js +69 -0
- package/dist/cli/chunk-27gtm2ym.js.map +11 -0
- package/dist/cli/chunk-2aj8ddew.js +72 -0
- package/dist/cli/chunk-2aj8ddew.js.map +10 -0
- package/dist/cli/chunk-3r94j3tc.js +221 -0
- package/dist/cli/chunk-3r94j3tc.js.map +10 -0
- package/dist/cli/chunk-4trphnvy.js +102 -0
- package/dist/cli/chunk-4trphnvy.js.map +11 -0
- package/dist/cli/chunk-4xyggvgf.js +21 -0
- package/dist/cli/chunk-4xyggvgf.js.map +10 -0
- package/dist/cli/chunk-5d4q7121.js +4064 -0
- package/dist/cli/chunk-5d4q7121.js.map +40 -0
- package/dist/cli/chunk-5hs6gb7n.js +32 -0
- package/dist/cli/chunk-5hs6gb7n.js.map +10 -0
- package/dist/cli/chunk-6kzzpsx8.js +26 -0
- package/dist/cli/chunk-6kzzpsx8.js.map +10 -0
- package/dist/cli/chunk-8gnpdsn1.js +952 -0
- package/dist/cli/chunk-8gnpdsn1.js.map +12 -0
- package/dist/cli/chunk-9qs6acpw.js +176 -0
- package/dist/cli/chunk-9qs6acpw.js.map +10 -0
- package/dist/cli/chunk-agy5rzxy.js +2453 -0
- package/dist/cli/chunk-agy5rzxy.js.map +15 -0
- package/dist/cli/chunk-bcy492zc.js +16 -0
- package/dist/cli/chunk-bcy492zc.js.map +10 -0
- package/dist/cli/chunk-btfr9yvw.js +41 -0
- package/dist/cli/chunk-btfr9yvw.js.map +10 -0
- package/dist/cli/chunk-cbjnx4s8.js +73 -0
- package/dist/cli/chunk-cbjnx4s8.js.map +10 -0
- package/dist/cli/chunk-cfw6x4rm.js +1967 -0
- package/dist/cli/chunk-cfw6x4rm.js.map +34 -0
- package/dist/cli/chunk-ckh3a410.js +277 -0
- package/dist/cli/chunk-ckh3a410.js.map +11 -0
- package/dist/cli/chunk-drke6t0h.js +259 -0
- package/dist/cli/chunk-drke6t0h.js.map +11 -0
- package/dist/cli/chunk-ev67ycx0.js +15 -0
- package/dist/cli/chunk-ev67ycx0.js.map +10 -0
- package/dist/cli/chunk-ey89bjj1.js +209 -0
- package/dist/cli/chunk-ey89bjj1.js.map +11 -0
- package/dist/cli/chunk-j6pxe0dt.js +69 -0
- package/dist/cli/chunk-j6pxe0dt.js.map +11 -0
- package/dist/cli/chunk-jk1zwka1.js +387 -0
- package/dist/cli/chunk-jk1zwka1.js.map +12 -0
- package/dist/cli/chunk-jtb45atp.js +467 -0
- package/dist/cli/chunk-jtb45atp.js.map +14 -0
- package/dist/cli/chunk-jxkxjsc1.js +76 -0
- package/dist/cli/chunk-jxkxjsc1.js.map +10 -0
- package/dist/cli/chunk-kwx90v78.js +81 -0
- package/dist/cli/chunk-kwx90v78.js.map +10 -0
- package/dist/cli/chunk-n0nyat6g.js +30 -0
- package/dist/cli/chunk-n0nyat6g.js.map +10 -0
- package/dist/cli/chunk-pxj10x8y.js +35 -0
- package/dist/cli/chunk-pxj10x8y.js.map +10 -0
- package/dist/cli/chunk-qq9nm3qd.js +1141 -0
- package/dist/cli/chunk-qq9nm3qd.js.map +19 -0
- package/dist/cli/chunk-s102bysw.js +5170 -0
- package/dist/cli/chunk-s102bysw.js.map +47 -0
- package/dist/cli/chunk-s5dsk8bj.js +769 -0
- package/dist/cli/chunk-s5dsk8bj.js.map +13 -0
- package/dist/cli/chunk-s5e5jt53.js +227 -0
- package/dist/cli/chunk-s5e5jt53.js.map +11 -0
- package/dist/cli/chunk-sbdqrjbb.js +81 -0
- package/dist/cli/chunk-sbdqrjbb.js.map +10 -0
- package/dist/cli/chunk-tnskyrej.js +117 -0
- package/dist/cli/chunk-tnskyrej.js.map +10 -0
- package/dist/cli/chunk-v2ymm99c.js +1016 -0
- package/dist/cli/chunk-v2ymm99c.js.map +13 -0
- package/dist/cli/chunk-v5mm027v.js +185 -0
- package/dist/cli/chunk-v5mm027v.js.map +11 -0
- package/dist/cli/chunk-vt8fgygt.js +23 -0
- package/dist/cli/chunk-vt8fgygt.js.map +10 -0
- package/dist/cli/chunk-vxv4x1n8.js +17 -0
- package/dist/cli/chunk-vxv4x1n8.js.map +10 -0
- package/dist/cli/chunk-wd27zjcz.js +60 -0
- package/dist/cli/chunk-wd27zjcz.js.map +10 -0
- package/dist/cli/chunk-x66c5yjn.js +23 -0
- package/dist/cli/chunk-x66c5yjn.js.map +10 -0
- package/dist/cli/chunk-xv91q4nm.js +5314 -0
- package/dist/cli/chunk-xv91q4nm.js.map +58 -0
- package/dist/cli/chunk-y3g15rvv.js +679 -0
- package/dist/cli/chunk-y3g15rvv.js.map +15 -0
- package/dist/cli/chunk-ye9zdkgv.js +136 -0
- package/dist/cli/chunk-ye9zdkgv.js.map +10 -0
- package/dist/cli/chunk-ynacq3ev.js +1062 -0
- package/dist/cli/chunk-ynacq3ev.js.map +25 -0
- package/dist/cli/chunk-zr3ygrq3.js +54 -0
- package/dist/cli/chunk-zr3ygrq3.js.map +10 -0
- package/dist/cli/index.js +55 -27597
- package/dist/cli/index.js.map +5 -243
- package/dist/types/ai/ask-context.d.ts +26 -0
- package/dist/types/components/layout/nav-utils.d.ts +33 -1
- package/dist/types/core/code-fences.d.ts +11 -0
- package/dist/types/core/package-root.d.ts +1 -1
- package/dist/types/core/schema.d.ts +70 -0
- package/dist/types/theme/fonts.d.ts +22 -22
- package/docs/02-deployment.mdx +22 -1
- package/docs/configuration/ask-ai.mdx +1 -1
- package/docs/configuration/customization.mdx +2 -9
- package/docs/content/navigation.mdx +2 -0
- package/docs/content/syntax.mdx +1 -1
- package/docs/discoverability/open-graph.mdx +4 -0
- package/docs/reference/cli.mdx +1 -1
- package/package.json +4 -2
- package/src/ai/api/handlers.ts +4 -7
- package/src/ai/api/paths.ts +8 -0
- package/src/ai/api/spec.ts +2 -1
- package/src/ai/ask-context.ts +378 -22
- package/src/astro/generate.ts +161 -28
- package/src/astro/include-hmr.ts +10 -13
- package/src/astro/include-refresh.ts +0 -0
- package/src/astro/index.ts +6 -1
- package/src/astro/integration.ts +280 -53
- package/src/astro/module-types.ts +83 -0
- package/src/astro/templates.ts +256 -108
- package/src/audit/image-size.ts +10 -8
- package/src/cli/command-meta.ts +77 -0
- package/src/cli/commands/add.ts +2 -4
- package/src/cli/commands/audit.ts +2 -4
- package/src/cli/commands/build.ts +70 -346
- package/src/cli/commands/check.ts +2 -4
- package/src/cli/commands/dev.ts +31 -42
- package/src/cli/commands/doctor.ts +2 -4
- package/src/cli/commands/eject.ts +3 -41
- package/src/cli/commands/eval.ts +2 -5
- package/src/cli/commands/init.ts +2 -4
- package/src/cli/commands/mcp-stdio.ts +2 -5
- package/src/cli/commands/preview.ts +3 -5
- package/src/cli/commands/sync.ts +2 -4
- package/src/cli/commands/translate.ts +2 -5
- package/src/cli/commands/validate.ts +2 -4
- package/src/cli/commands/version.ts +2 -4
- package/src/cli/eject-scripts.ts +0 -45
- package/src/cli/host-args.ts +16 -0
- package/src/cli/index.ts +84 -35
- package/src/cli/lazy-command.ts +47 -0
- package/src/components/Icon.astro +24 -0
- package/src/components/content/GithubInfo.astro +4 -1
- package/src/components/icon-sprite-middleware.ts +41 -0
- package/src/components/icon-sprite.ts +93 -0
- package/src/components/layout/IconSprite.astro +11 -0
- package/src/components/layout/NavTree.astro +156 -188
- package/src/components/layout/NavTreeCache.astro +45 -0
- package/src/components/layout/NavTreeScript.astro +256 -0
- package/src/components/layout/PageActions.astro +11 -5
- package/src/components/layout/PageLayout.astro +21 -3
- package/src/components/layout/ReferenceLayout.astro +21 -4
- package/src/components/layout/RootLayout.astro +44 -6
- package/src/components/layout/nav-cache.ts +49 -0
- package/src/components/layout/nav-utils.ts +69 -1
- package/src/components/layout/page-locale.ts +29 -0
- package/src/core/api-name.ts +18 -0
- package/src/core/code-fences.ts +48 -0
- package/src/core/content-assets.ts +3 -7
- package/src/core/includes.ts +3 -7
- package/src/core/package-root.ts +1 -1
- package/src/core/schema.ts +19 -0
- package/src/core/sources/normalize.ts +2 -37
- package/src/core/sources/obsidian.ts +3 -2
- package/src/core/svg-dimensions.ts +97 -0
- package/src/core/version-cut.ts +2 -2
- package/src/deploy/artifacts.ts +370 -0
- package/src/deploy/cloudflare-negotiation.ts +97 -32
- package/src/deploy/function-bundle.ts +66 -20
- package/src/deploy/sitemap.ts +6 -0
- package/src/deploy/vercel-negotiation.ts +8 -30
- package/src/markdown/language-icon.ts +64 -20
- package/src/markdown/mermaid.ts +11 -0
- package/src/og/cache.ts +236 -0
- package/src/og/card.ts +18 -16
- package/src/og/index.ts +8 -1
- package/src/openapi/render-mdx.ts +9 -5
- package/src/registry/eject.ts +23 -10
- package/src/theme/entry.ts +41 -7
- package/src/theme/fonts.ts +30 -23
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { isImageIcon, isInlineSvg } from "../theme/icon-kind.ts";
|
|
3
3
|
import { resolveIcon } from "../theme/icons.ts";
|
|
4
|
+
import { iconSpriteFor, registerIconSymbol } from "./icon-sprite.ts";
|
|
4
5
|
import { withBase } from "./islands/base-path.ts";
|
|
5
6
|
|
|
6
7
|
interface Props {
|
|
@@ -32,6 +33,17 @@ const rawSvg = iconName && isInlineSvg(iconName) ? iconName.trim() : null;
|
|
|
32
33
|
const imageSrc = iconName && !rawSvg && isImageIcon(iconName) ? iconName : null;
|
|
33
34
|
const resolvedIcon =
|
|
34
35
|
iconName && !(imageSrc || rawSvg) ? resolveIcon(iconName) : null;
|
|
36
|
+
// A set icon joins the page's sprite when the shell keeps one (see
|
|
37
|
+
// icon-sprite.ts): the paths render once, in the sprite, and this use is a
|
|
38
|
+
// <use> reference. Without a sprite the icon inlines its paths as before.
|
|
39
|
+
const sprite = resolvedIcon ? iconSpriteFor(Astro.locals) : undefined;
|
|
40
|
+
const symbolId =
|
|
41
|
+
sprite && resolvedIcon
|
|
42
|
+
? registerIconSymbol(sprite, resolvedIcon.name, {
|
|
43
|
+
body: resolvedIcon.body,
|
|
44
|
+
viewBox: resolvedIcon.viewBox,
|
|
45
|
+
})
|
|
46
|
+
: null;
|
|
35
47
|
const resolvedClass = astroClass ?? className;
|
|
36
48
|
const customStyle = `display:inline-flex;width:${size}px;height:${size}px;${
|
|
37
49
|
color ? `color:${color}` : ""
|
|
@@ -68,6 +80,18 @@ const style = color ? `color:${color}` : undefined;
|
|
|
68
80
|
src={withBase(imageSrc)}
|
|
69
81
|
width={size}
|
|
70
82
|
/>
|
|
83
|
+
) : symbolId ? (
|
|
84
|
+
<svg
|
|
85
|
+
aria-hidden={label ? undefined : "true"}
|
|
86
|
+
aria-label={label}
|
|
87
|
+
class={resolvedClass}
|
|
88
|
+
height={size}
|
|
89
|
+
role={label ? "img" : undefined}
|
|
90
|
+
style={style}
|
|
91
|
+
width={size}
|
|
92
|
+
>
|
|
93
|
+
<use href={`#${symbolId}`} />
|
|
94
|
+
</svg>
|
|
71
95
|
) : (
|
|
72
96
|
resolvedIcon && (
|
|
73
97
|
<svg
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// at build time (no client JS). Pass `owner`/`repo`, or omit them to use the
|
|
4
4
|
// repo from blume.config. A `GITHUB_TOKEN` env var lifts the API rate limit.
|
|
5
5
|
// If the API is unreachable the card still renders, just without counts.
|
|
6
|
+
import { getSecret } from "astro:env/server";
|
|
6
7
|
import { apiUrl, PUBLIC_HOST_URL } from "../../core/github.ts";
|
|
7
8
|
import { resolveIcon } from "../../theme/icons.ts";
|
|
8
9
|
import data from "blume:data";
|
|
@@ -38,7 +39,9 @@ interface Props {
|
|
|
38
39
|
const configured = data.config.github;
|
|
39
40
|
const owner = Astro.props.owner ?? configured?.owner;
|
|
40
41
|
const repo = Astro.props.repo ?? configured?.repo;
|
|
41
|
-
|
|
42
|
+
// Read through Astro's `getSecret` so the adapter's secret store is honored
|
|
43
|
+
// (the card renders at build time, where that is the environment).
|
|
44
|
+
const token = Astro.props.token ?? getSecret("GITHUB_TOKEN");
|
|
42
45
|
// A `host` prop is reduced to its origin, as the config field is, so a
|
|
43
46
|
// trailing slash or a path never lands mid-link.
|
|
44
47
|
const host = Astro.props.host
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from "astro";
|
|
2
|
+
|
|
3
|
+
import { iconSpriteFor, renderIconSprite } from "./icon-sprite.ts";
|
|
4
|
+
import type { IconSprite } from "./icon-sprite.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The placeholder a shell renders where its icon sprite goes (the end of the
|
|
8
|
+
* body); {@link onRequest} replaces it once the page has fully rendered.
|
|
9
|
+
* Rendering the sprite from a component instead wouldn't work: Astro walks a
|
|
10
|
+
* template's own markup before its nested components render, so a sprite
|
|
11
|
+
* component at the end of the body runs before the header's search button or
|
|
12
|
+
* the page content's callouts have registered their icons.
|
|
13
|
+
*/
|
|
14
|
+
export const ICON_SPRITE_SLOT = "<!--blume-icon-sprite-->";
|
|
15
|
+
|
|
16
|
+
/** The page HTML with its placeholder replaced by the finished sprite. */
|
|
17
|
+
export const spliceIconSprite = (html: string, sprite?: IconSprite): string =>
|
|
18
|
+
html.includes(ICON_SPRITE_SLOT)
|
|
19
|
+
? html.replace(ICON_SPRITE_SLOT, sprite ? renderIconSprite(sprite) : "")
|
|
20
|
+
: html;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Blume's icon-sprite middleware (wired by the integration). Draining the
|
|
24
|
+
* response renders the whole page, after which the request's registry holds
|
|
25
|
+
* every icon it used; the sprite is spliced in where the shell left the slot.
|
|
26
|
+
* Requests whose shell kept no registry — a user layout override, a partial,
|
|
27
|
+
* an endpoint — pass through untouched, streaming and all.
|
|
28
|
+
*/
|
|
29
|
+
export const onRequest: MiddlewareHandler = async (context, render) => {
|
|
30
|
+
const response = await render();
|
|
31
|
+
const sprite = iconSpriteFor(context.locals);
|
|
32
|
+
if (!sprite) {
|
|
33
|
+
return response;
|
|
34
|
+
}
|
|
35
|
+
const html = await response.text();
|
|
36
|
+
return new Response(spliceIconSprite(html, sprite), {
|
|
37
|
+
headers: response.headers,
|
|
38
|
+
status: response.status,
|
|
39
|
+
statusText: response.statusText,
|
|
40
|
+
});
|
|
41
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A per-page SVG sprite for the icon sets. A page renders the same handful of
|
|
3
|
+
* icons many times over (every sidebar chevron, every code-block language
|
|
4
|
+
* icon, the page-action buttons); inlining each one repeats its paths on every
|
|
5
|
+
* use, which on a docs page is ~20 kB of the ~60 kB that isn't the sidebar.
|
|
6
|
+
* With the sprite, each use is a `<use href="#…">` reference and the paths
|
|
7
|
+
* appear once, in a hidden `<svg>` the layout renders at the end of the body.
|
|
8
|
+
*
|
|
9
|
+
* The registry lives on the request's `Astro.locals`, so every component in
|
|
10
|
+
* one page render — the layout, the MDX content, cached sidebar subtrees —
|
|
11
|
+
* shares it, and concurrent page renders never see each other's icons. A
|
|
12
|
+
* shell that creates no registry (a user's layout override, a partial) gets
|
|
13
|
+
* inline icons, exactly as before.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** One symbol in the sprite: an icon set's inner markup and its viewBox. */
|
|
17
|
+
export interface IconSymbol {
|
|
18
|
+
body: string;
|
|
19
|
+
viewBox: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface IconSprite {
|
|
23
|
+
/** Symbol id → symbol, in first-use order. */
|
|
24
|
+
symbols: Map<string, IconSymbol>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** The request locals (`Astro.locals`) slot the registry lives in. */
|
|
28
|
+
export interface IconSpriteLocals {
|
|
29
|
+
blumeIconSprite?: IconSprite;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The request's sprite registry, when a shell created one. */
|
|
33
|
+
export const iconSpriteFor = (
|
|
34
|
+
locals: IconSpriteLocals
|
|
35
|
+
): IconSprite | undefined => locals.blumeIconSprite;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The request's sprite registry, created on first call: a shell calls this
|
|
39
|
+
* up front. Idempotent, so a shell rendered inside another shell's request
|
|
40
|
+
* joins the existing registry instead of discarding its icons.
|
|
41
|
+
*/
|
|
42
|
+
export const createIconSprite = (locals: IconSpriteLocals): IconSprite => {
|
|
43
|
+
locals.blumeIconSprite ??= { symbols: new Map() };
|
|
44
|
+
return locals.blumeIconSprite;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The sprite symbol id for an icon name. Names come from config and content
|
|
49
|
+
* (`lucide:arrow-right`, `simple-icons:github`), so anything outside the id
|
|
50
|
+
* charset is folded to a dash.
|
|
51
|
+
*/
|
|
52
|
+
export const iconSymbolId = (name: string): string =>
|
|
53
|
+
`blume-i-${name.toLowerCase().replaceAll(/[^a-z0-9-]+/gu, "-")}`;
|
|
54
|
+
|
|
55
|
+
/** Register a symbol (idempotent) and return its id. */
|
|
56
|
+
export const registerIconSymbol = (
|
|
57
|
+
sprite: IconSprite,
|
|
58
|
+
name: string,
|
|
59
|
+
symbol: IconSymbol
|
|
60
|
+
): string => {
|
|
61
|
+
const id = iconSymbolId(name);
|
|
62
|
+
if (!sprite.symbols.has(id)) {
|
|
63
|
+
sprite.symbols.set(id, symbol);
|
|
64
|
+
}
|
|
65
|
+
return id;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/** The ids of every sprite symbol a rendered HTML fragment references. */
|
|
69
|
+
export const referencedIconSymbols = (html: string): string[] => [
|
|
70
|
+
...new Set(
|
|
71
|
+
[...html.matchAll(/href="#(?<id>blume-i-[^"]+)"/gu)].map(
|
|
72
|
+
(match) => match.groups?.id ?? ""
|
|
73
|
+
)
|
|
74
|
+
),
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The hidden sprite `<svg>` holding every registered symbol, or an empty
|
|
79
|
+
* string when the page used no set icon. Symbol bodies are the icon sets'
|
|
80
|
+
* own markup (already SVG); the viewBox is the only attribute interpolated.
|
|
81
|
+
*/
|
|
82
|
+
export const renderIconSprite = (sprite: IconSprite): string => {
|
|
83
|
+
if (sprite.symbols.size === 0) {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
const symbols = [...sprite.symbols]
|
|
87
|
+
.map(
|
|
88
|
+
([id, symbol]) =>
|
|
89
|
+
`<symbol id="${id}" viewBox="${symbol.viewBox}">${symbol.body}</symbol>`
|
|
90
|
+
)
|
|
91
|
+
.join("");
|
|
92
|
+
return `<svg aria-hidden="true" hidden xmlns="http://www.w3.org/2000/svg">${symbols}</svg>`;
|
|
93
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Where the page's icon sprite goes: every set icon the render registered
|
|
3
|
+
// (see icon-sprite.ts), as one hidden <svg> of <symbol>s the icons' <use>
|
|
4
|
+
// references resolve against. This only leaves a placeholder at the end of
|
|
5
|
+
// the body; the icon-sprite middleware replaces it once the page has fully
|
|
6
|
+
// rendered, since a component here would run before nested components
|
|
7
|
+
// (the header's search button, the content's callouts) register their icons.
|
|
8
|
+
import { ICON_SPRITE_SLOT } from "../icon-sprite-middleware.ts";
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<Fragment set:html={ICON_SPRITE_SLOT} />
|