blume 1.7.2 → 2.0.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/AGENTS.md +19 -0
- package/CHANGELOG.md +227 -0
- package/README.md +34 -21
- package/dist/cli/chunk-11j0384y.js +148 -0
- package/dist/cli/chunk-11j0384y.js.map +10 -0
- package/dist/cli/{chunk-xhtpx3ff.js → chunk-1w8dp3qb.js} +17 -16
- package/dist/cli/{chunk-xhtpx3ff.js.map → chunk-1w8dp3qb.js.map} +3 -3
- package/dist/cli/chunk-2q1dwty4.js +75 -0
- package/dist/cli/chunk-2q1dwty4.js.map +11 -0
- package/dist/cli/chunk-41za066z.js +122 -0
- package/dist/cli/chunk-41za066z.js.map +11 -0
- package/dist/cli/chunk-5a2z0198.js +133 -0
- package/dist/cli/chunk-5a2z0198.js.map +10 -0
- package/dist/cli/{chunk-9he6crym.js → chunk-6k8vp3ta.js} +25 -13
- package/dist/cli/{chunk-9he6crym.js.map → chunk-6k8vp3ta.js.map} +4 -4
- package/dist/cli/{chunk-mt76t7dj.js → chunk-79njf86q.js} +133 -54
- package/dist/cli/chunk-79njf86q.js.map +11 -0
- package/dist/cli/{chunk-3w7b2vcx.js → chunk-7ez8ny0t.js} +2 -2
- package/dist/cli/{chunk-688e0dde.js → chunk-88cpgt6h.js} +1 -1
- package/dist/cli/chunk-a9kptbw5.js +361 -0
- package/dist/cli/chunk-a9kptbw5.js.map +14 -0
- package/dist/cli/chunk-abh8yjkn.js +31 -0
- package/dist/cli/chunk-abh8yjkn.js.map +10 -0
- package/dist/cli/chunk-b5aj94ah.js +91 -0
- package/dist/cli/chunk-b5aj94ah.js.map +10 -0
- package/dist/cli/{chunk-hs3gbh8p.js → chunk-bctazmbk.js} +9 -5
- package/dist/cli/chunk-bctazmbk.js.map +10 -0
- package/dist/cli/chunk-beat36xx.js +279 -0
- package/dist/cli/chunk-beat36xx.js.map +10 -0
- package/dist/cli/chunk-bnbmcwfb.js +145 -0
- package/dist/cli/chunk-bnbmcwfb.js.map +11 -0
- package/dist/cli/{chunk-9bkjd11x.js → chunk-bw22s759.js} +15 -5
- package/dist/cli/{chunk-9bkjd11x.js.map → chunk-bw22s759.js.map} +4 -4
- package/dist/cli/chunk-by2290sx.js +39 -0
- package/dist/cli/chunk-by2290sx.js.map +10 -0
- package/dist/cli/chunk-d1tadaw7.js +79 -0
- package/dist/cli/chunk-d1tadaw7.js.map +10 -0
- package/dist/cli/{chunk-t3tj0dgr.js → chunk-d80hr03s.js} +24 -19
- package/dist/cli/chunk-d80hr03s.js.map +15 -0
- package/dist/cli/chunk-ernrthtr.js +97 -0
- package/dist/cli/chunk-ernrthtr.js.map +10 -0
- package/dist/cli/chunk-f2972sbt.js +374 -0
- package/dist/cli/chunk-f2972sbt.js.map +10 -0
- package/dist/cli/{chunk-exeeb35e.js → chunk-f7t03s3g.js} +2 -2
- package/dist/cli/{chunk-2z47ypj8.js → chunk-fa25z98p.js} +16 -3
- package/dist/cli/chunk-fa25z98p.js.map +11 -0
- package/dist/cli/{chunk-12dxjqk7.js → chunk-fh5hj5jt.js} +44 -21
- package/dist/cli/chunk-fh5hj5jt.js.map +10 -0
- package/dist/cli/{chunk-8cd8tj54.js → chunk-j8mw0za6.js} +86 -57
- package/dist/cli/chunk-j8mw0za6.js.map +35 -0
- package/dist/cli/chunk-jts8mvcz.js +106 -0
- package/dist/cli/{chunk-2mzebbbz.js.map → chunk-jts8mvcz.js.map} +6 -4
- package/dist/cli/{chunk-ejjx8znq.js → chunk-mnqj32sj.js} +505 -536
- package/dist/cli/chunk-mnqj32sj.js.map +12 -0
- package/dist/cli/{chunk-196vjxp9.js → chunk-mwt1k8n7.js} +100 -372
- package/dist/cli/chunk-mwt1k8n7.js.map +10 -0
- package/dist/cli/chunk-nk3ts2xk.js +51 -0
- package/dist/cli/chunk-nk3ts2xk.js.map +10 -0
- package/dist/cli/{chunk-n9sra6sy.js → chunk-pat2zzwc.js} +10 -14
- package/dist/cli/{chunk-n9sra6sy.js.map → chunk-pat2zzwc.js.map} +2 -2
- package/dist/cli/chunk-pnnvybbk.js +176 -0
- package/dist/cli/chunk-pnnvybbk.js.map +11 -0
- package/dist/cli/{chunk-cvky9gb2.js → chunk-sqn5t4q0.js} +81 -87
- package/dist/cli/chunk-sqn5t4q0.js.map +10 -0
- package/dist/cli/{chunk-eevwt1sc.js → chunk-tzne8qfq.js} +15 -15
- package/dist/cli/{chunk-eevwt1sc.js.map → chunk-tzne8qfq.js.map} +1 -1
- package/dist/cli/chunk-xaz13gwg.js +12449 -0
- package/dist/cli/chunk-xaz13gwg.js.map +182 -0
- package/dist/cli/chunk-y3e45rc8.js +102 -0
- package/dist/cli/chunk-y3e45rc8.js.map +10 -0
- package/dist/cli/chunk-z01ze5c1.js +261 -0
- package/dist/cli/chunk-z01ze5c1.js.map +10 -0
- package/dist/cli/{chunk-5n7t497w.js → chunk-z1f5arsg.js} +247 -755
- package/dist/cli/chunk-z1f5arsg.js.map +36 -0
- package/dist/cli/{chunk-hdm2dkd2.js → chunk-zg2gtj10.js} +1086 -2596
- package/dist/cli/chunk-zg2gtj10.js.map +35 -0
- package/dist/cli/{chunk-ppfvdcd4.js → chunk-zxccj738.js} +1 -1
- package/dist/cli/index.js +214 -57
- package/dist/cli/index.js.map +8 -7
- package/dist/types/ai/agent-readability.d.ts +52 -0
- package/dist/types/ai/ai-catalog.d.ts +42 -0
- package/dist/types/ai/api/paths.d.ts +17 -0
- package/dist/types/ai/api-catalog.d.ts +18 -0
- package/dist/types/ai/ask.d.ts +368 -0
- package/dist/types/ai/changelog-markdown.d.ts +2 -0
- package/dist/types/ai/component-markdown.d.ts +2 -2
- package/dist/types/ai/index.d.ts +24 -0
- package/dist/types/ai/link-headers.d.ts +24 -0
- package/dist/types/ai/llms.d.ts +25 -0
- package/dist/types/ai/markdown.d.ts +45 -0
- package/dist/types/ai/mcp/discovery.d.ts +68 -0
- package/dist/types/ai/mcp/tools.d.ts +16 -0
- package/dist/types/ai/openapi-components.d.ts +43 -0
- package/dist/types/ai/relative-links.d.ts +26 -0
- package/dist/types/ai/serializers.d.ts +15 -0
- package/dist/types/ai/skills.d.ts +42 -0
- package/dist/types/ai/tar.d.ts +25 -0
- package/dist/types/ai/visibility.d.ts +17 -0
- package/dist/types/ai/web-bot-auth.d.ts +16 -0
- package/dist/types/analytics/adobe.d.ts +35 -0
- package/dist/types/analytics/amplitude.d.ts +50 -0
- package/dist/types/analytics/clarity.d.ts +31 -0
- package/dist/types/analytics/clearbit.d.ts +29 -0
- package/dist/types/analytics/cloudflare.d.ts +41 -0
- package/dist/types/analytics/fathom.d.ts +41 -0
- package/dist/types/analytics/google-analytics.d.ts +44 -0
- package/dist/types/analytics/google-tag-manager.d.ts +40 -0
- package/dist/types/analytics/head.d.ts +30 -0
- package/dist/types/analytics/heap.d.ts +40 -0
- package/dist/types/analytics/hightouch.d.ts +44 -0
- package/dist/types/analytics/hotjar.d.ts +33 -0
- package/dist/types/analytics/index.d.ts +61 -0
- package/dist/types/analytics/inline.d.ts +17 -0
- package/dist/types/analytics/logrocket.d.ts +44 -0
- package/dist/types/analytics/mixpanel.d.ts +67 -0
- package/dist/types/analytics/pirsch.d.ts +42 -0
- package/dist/types/analytics/plausible.d.ts +56 -0
- package/dist/types/analytics/posthog.d.ts +45 -0
- package/dist/types/analytics/schema.d.ts +320 -0
- package/dist/types/analytics/script.d.ts +46 -0
- package/dist/types/analytics/segment.d.ts +50 -0
- package/dist/types/analytics/vercel.d.ts +48 -0
- package/dist/types/astro/integration.d.ts +76 -0
- package/dist/types/astro/markdown-negotiation.d.ts +23 -0
- package/dist/types/astro/module-types.d.ts +14 -0
- package/dist/types/astro/pages.d.ts +44 -0
- package/dist/types/cli/env.d.ts +12 -0
- package/dist/types/cli/init/scaffold.d.ts +154 -0
- package/dist/types/components/layout/nav-utils.d.ts +11 -0
- package/dist/types/core/adapter.d.ts +47 -0
- package/dist/types/core/api-name.d.ts +7 -0
- package/dist/types/core/changelog-index.d.ts +13 -0
- package/dist/types/core/config-input.d.ts +209 -505
- package/dist/types/core/config.d.ts +60 -34
- package/dist/types/core/content-assets.d.ts +76 -0
- package/dist/types/core/custom-pages.d.ts +33 -0
- package/dist/types/core/data.d.ts +28 -11
- package/dist/types/core/define-components.d.ts +12 -9
- package/dist/types/core/deployment-env.d.ts +6 -11
- package/dist/types/core/frontmatter.d.ts +10 -0
- package/dist/types/core/graph.d.ts +18 -0
- package/dist/types/core/heading-markers.d.ts +54 -0
- package/dist/types/core/i18n-ui.d.ts +6 -2
- package/dist/types/core/i18n.d.ts +87 -0
- package/dist/types/core/includes.d.ts +138 -0
- package/dist/types/core/last-modified.d.ts +47 -0
- package/dist/types/core/links.d.ts +95 -0
- package/dist/types/core/locale-links.d.ts +60 -0
- package/dist/types/core/manifest.d.ts +17 -0
- package/dist/types/core/meta.d.ts +38 -0
- package/dist/types/core/nav-diagnostics.d.ts +26 -0
- package/dist/types/core/navigation.d.ts +6 -0
- package/dist/types/core/node-require.d.ts +19 -0
- package/dist/types/core/package-json.d.ts +13 -0
- package/dist/types/core/probe.d.ts +42 -0
- package/dist/types/core/project-graph.d.ts +51 -0
- package/dist/types/core/project.d.ts +2 -0
- package/dist/types/core/safe-href.d.ts +2 -0
- package/dist/types/core/safe-links.d.ts +26 -0
- package/dist/types/core/schema.d.ts +2291 -441
- package/dist/types/core/site-url.d.ts +16 -0
- package/dist/types/core/sources/assets.d.ts +36 -0
- package/dist/types/core/sources/cache.d.ts +37 -0
- package/dist/types/core/sources/collection.d.ts +28 -0
- package/dist/types/core/sources/contentful-rich-text.d.ts +31 -0
- package/dist/types/core/sources/contentful.d.ts +40 -0
- package/dist/types/core/sources/filesystem.d.ts +24 -0
- package/dist/types/core/sources/github-releases.d.ts +31 -0
- package/dist/types/core/sources/json.d.ts +30 -0
- package/dist/types/core/sources/lexical.d.ts +19 -0
- package/dist/types/core/sources/lower.d.ts +75 -0
- package/dist/types/core/sources/mdx-remote.d.ts +28 -0
- package/dist/types/core/sources/normalize.d.ts +147 -0
- package/dist/types/core/sources/notion.d.ts +131 -0
- package/dist/types/core/sources/obsidian.d.ts +46 -0
- package/dist/types/core/sources/payload.d.ts +39 -0
- package/dist/types/core/sources/portable-text.d.ts +42 -0
- package/dist/types/core/sources/read.d.ts +23 -0
- package/dist/types/core/sources/remote.d.ts +74 -0
- package/dist/types/core/sources/resolve.d.ts +19 -0
- package/dist/types/core/sources/sanity.d.ts +43 -0
- package/dist/types/core/sources/strapi-blocks.d.ts +12 -0
- package/dist/types/core/sources/strapi.d.ts +33 -0
- package/dist/types/core/sources/types.d.ts +7 -0
- package/dist/types/core/sources/watch.d.ts +45 -0
- package/dist/types/core/text-width.d.ts +11 -0
- package/dist/types/core/types.d.ts +20 -1
- package/dist/types/core/unrecognized-keys.d.ts +7 -0
- package/dist/types/core/versions.d.ts +72 -0
- package/dist/types/core/yaml.d.ts +9 -0
- package/dist/types/deploy/adapter-output.d.ts +45 -0
- package/dist/types/deploy/adapters/cloudflare.d.ts +40 -0
- package/dist/types/deploy/adapters/index.d.ts +29 -0
- package/dist/types/deploy/adapters/netlify.d.ts +37 -0
- package/dist/types/deploy/adapters/node.d.ts +37 -0
- package/dist/types/deploy/adapters/registry.d.ts +133 -0
- package/dist/types/deploy/adapters/types.d.ts +71 -0
- package/dist/types/deploy/adapters/vercel.d.ts +38 -0
- package/dist/types/deploy/artifacts.d.ts +65 -0
- package/dist/types/deploy/cloudflare-negotiation.d.ts +196 -0
- package/dist/types/deploy/function-bundle.d.ts +80 -0
- package/dist/types/deploy/headers.d.ts +50 -0
- package/dist/types/deploy/node-headers.d.ts +42 -0
- package/dist/types/deploy/platforms/cloudflare.d.ts +40 -0
- package/dist/types/deploy/platforms/index.d.ts +18 -0
- package/dist/types/deploy/platforms/netlify.d.ts +13 -0
- package/dist/types/deploy/platforms/node.d.ts +11 -0
- package/dist/types/deploy/platforms/paths.d.ts +27 -0
- package/dist/types/deploy/platforms/static.d.ts +10 -0
- package/dist/types/deploy/platforms/types.d.ts +104 -0
- package/dist/types/deploy/platforms/vercel.d.ts +32 -0
- package/dist/types/deploy/redirects.d.ts +53 -0
- package/dist/types/deploy/robots.d.ts +8 -0
- package/dist/types/deploy/rss.d.ts +31 -0
- package/dist/types/deploy/sitemap.d.ts +21 -0
- package/dist/types/deploy/vercel-negotiation.d.ts +109 -0
- package/dist/types/markdown/code-title.d.ts +32 -0
- package/dist/types/markdown/fence-meta.d.ts +23 -0
- package/dist/types/markdown/themes.d.ts +3 -3
- package/dist/types/openapi/asyncapi.d.ts +129 -0
- package/dist/types/openapi/graphql-build.d.ts +8 -0
- package/dist/types/openapi/graphql.d.ts +122 -0
- package/dist/types/openapi/model.d.ts +158 -0
- package/dist/types/openapi/parse.d.ts +57 -0
- package/dist/types/openapi/references.d.ts +37 -25
- package/dist/types/openapi/render-mdx.d.ts +33 -0
- package/dist/types/openapi/sentence.d.ts +7 -0
- package/dist/types/openapi/signature.d.ts +10 -0
- package/dist/types/openapi/source.d.ts +22 -0
- package/dist/types/openapi/spec-dependency-error.d.ts +10 -0
- package/dist/types/reference/asyncapi.d.ts +166 -0
- package/dist/types/reference/graphql.d.ts +181 -0
- package/dist/types/reference/index.d.ts +32 -0
- package/dist/types/reference/openapi.d.ts +165 -0
- package/dist/types/reference/options.d.ts +157 -0
- package/dist/types/reference/scalar.d.ts +136 -0
- package/dist/types/reference/schema.d.ts +630 -0
- package/dist/types/search/adapters/algolia.d.ts +32 -0
- package/dist/types/search/adapters/flexsearch.d.ts +12 -0
- package/dist/types/search/adapters/index.d.ts +31 -0
- package/dist/types/search/adapters/mixedbread.d.ts +22 -0
- package/dist/types/search/adapters/orama-cloud.d.ts +33 -0
- package/dist/types/search/adapters/orama.d.ts +13 -0
- package/dist/types/search/adapters/pagefind.d.ts +12 -0
- package/dist/types/search/adapters/registry.d.ts +228 -0
- package/dist/types/search/adapters/types.d.ts +34 -0
- package/dist/types/search/adapters/typesense.d.ts +42 -0
- package/dist/types/search/build.d.ts +23 -0
- package/dist/types/search/documents.d.ts +90 -0
- package/dist/types/search/facets.d.ts +3 -0
- package/dist/types/search/sync/algolia.d.ts +14 -0
- package/dist/types/search/sync/index.d.ts +14 -0
- package/dist/types/search/sync/orama-cloud.d.ts +10 -0
- package/dist/types/search/sync/typesense.d.ts +14 -0
- package/dist/types/sources/contentful.d.ts +68 -0
- package/dist/types/sources/custom.d.ts +20 -0
- package/dist/types/sources/filesystem.d.ts +42 -0
- package/dist/types/sources/github-releases.d.ts +46 -0
- package/dist/types/sources/index.d.ts +48 -0
- package/dist/types/sources/mdx-remote.d.ts +63 -0
- package/dist/types/sources/notion.d.ts +65 -0
- package/dist/types/sources/obsidian.d.ts +34 -0
- package/dist/types/sources/payload.d.ts +68 -0
- package/dist/types/sources/registry.d.ts +1414 -0
- package/dist/types/sources/sanity.d.ts +69 -0
- package/dist/types/sources/shared.d.ts +46 -0
- package/dist/types/sources/strapi.d.ts +66 -0
- package/dist/types/theme/icon-kind.d.ts +11 -0
- package/dist/types/theme/icons.d.ts +20 -0
- package/docs/01-quickstart.mdx +18 -18
- package/docs/02-deployment.mdx +50 -26
- package/docs/03-upgrading.mdx +351 -0
- package/docs/04-migrating.mdx +58 -0
- package/docs/08-faq.mdx +3 -3
- package/docs/advanced/blog.mdx +13 -6
- package/docs/advanced/changelog.mdx +23 -35
- package/docs/advanced/custom-pages.mdx +20 -8
- package/docs/advanced/meta.ts +1 -8
- package/docs/advanced/skills.mdx +8 -0
- package/docs/cli/audit.mdx +646 -0
- package/docs/cli/doctor.mdx +29 -0
- package/docs/{reference/eval.mdx → cli/evals.mdx} +9 -8
- package/docs/cli/index.mdx +105 -0
- package/docs/cli/meta.ts +7 -0
- package/docs/{reference → cli}/translate.mdx +1 -1
- package/docs/cli/validate.mdx +41 -0
- package/docs/cli/version.mdx +40 -0
- package/docs/configuration/analytics.mdx +350 -59
- package/docs/configuration/ask-ai.mdx +176 -61
- package/docs/configuration/customization.mdx +15 -9
- package/docs/configuration/index.mdx +52 -31
- package/docs/configuration/search.mdx +75 -54
- package/docs/configuration/theming.mdx +24 -15
- package/docs/content/components.mdx +21 -5
- package/docs/{reference → content}/frontmatter.mdx +37 -1
- package/docs/content/i18n.mdx +8 -6
- package/docs/content/includes.mdx +2 -4
- package/docs/content/index.mdx +1 -1
- package/docs/content/islands.mdx +10 -5
- package/docs/content/meta.mdx +1 -1
- package/docs/content/meta.ts +1 -0
- package/docs/content/navigation.mdx +12 -7
- package/docs/content/sources.mdx +145 -50
- package/docs/content/syntax.mdx +26 -12
- package/docs/content/versioning.mdx +3 -3
- package/docs/discoverability/agent-discovery.mdx +91 -10
- package/docs/discoverability/index.mdx +5 -5
- package/docs/discoverability/json-api.mdx +4 -4
- package/docs/discoverability/llms-txt.mdx +6 -6
- package/docs/discoverability/markdown.mdx +4 -4
- package/docs/discoverability/mcp.mdx +11 -11
- package/docs/discoverability/sitemap-and-robots.mdx +3 -3
- package/docs/index.mdx +2 -2
- package/docs/references/asyncapi.mdx +59 -0
- package/docs/{advanced → references}/graphql.mdx +45 -32
- package/docs/{reference → references}/meta.ts +2 -2
- package/docs/references/openapi.mdx +171 -0
- package/docs/references/scalar.mdx +64 -0
- package/package.json +42 -8
- package/skills/blume/SKILL.md +21 -8
- package/skills/blume-migrate/SKILL.md +22 -21
- package/skills/blume-migrate/assets/oxfmt@0.67.0.patch +49 -0
- package/skills/blume-migrate/references/docusaurus.md +5 -4
- package/skills/blume-migrate/references/fumadocs.md +4 -4
- package/skills/blume-migrate/references/mintlify.md +23 -8
- package/skills/blume-migrate/references/monorepo.md +6 -6
- package/skills/blume-migrate/references/starlight.md +4 -4
- package/src/ai/agent-readability.ts +26 -22
- package/src/ai/ai-catalog.ts +259 -0
- package/src/ai/api/handlers.ts +46 -11
- package/src/ai/api-catalog.ts +8 -8
- package/src/ai/ask-data.ts +1 -1
- package/src/ai/ask.ts +624 -100
- package/src/ai/changelog-markdown.ts +91 -0
- package/src/ai/component-markdown.ts +328 -12
- package/src/ai/index.ts +45 -0
- package/src/ai/link-headers.ts +19 -6
- package/src/ai/llms.ts +26 -15
- package/src/ai/markdown.ts +35 -5
- package/src/ai/mcp/data.ts +9 -5
- package/src/ai/mcp/discovery.ts +1 -1
- package/src/ai/openapi-components.ts +4 -1
- package/src/ai/relative-links.ts +170 -0
- package/src/ai/serializers.ts +2 -2
- package/src/ai/skills.ts +1 -1
- package/src/ai/web-bot-auth.ts +2 -2
- package/src/analytics/adobe.ts +46 -0
- package/src/analytics/amplitude.ts +79 -0
- package/src/analytics/clarity.ts +46 -0
- package/src/analytics/clearbit.ts +47 -0
- package/src/analytics/cloudflare.ts +67 -0
- package/src/analytics/fathom.ts +64 -0
- package/src/analytics/google-analytics.ts +84 -0
- package/src/analytics/google-tag-manager.ts +61 -0
- package/src/analytics/head.ts +130 -0
- package/src/analytics/heap.ts +65 -0
- package/src/analytics/hightouch.ts +77 -0
- package/src/analytics/hotjar.ts +47 -0
- package/src/analytics/index.ts +71 -0
- package/src/analytics/inline.ts +21 -0
- package/src/analytics/logrocket.ts +71 -0
- package/src/analytics/mixpanel.ts +92 -0
- package/src/analytics/pirsch.ts +66 -0
- package/src/analytics/plausible.ts +83 -0
- package/src/analytics/posthog.ts +78 -0
- package/src/analytics/schema.ts +60 -0
- package/src/analytics/script.ts +60 -0
- package/src/analytics/segment.ts +85 -0
- package/src/analytics/vercel.ts +50 -0
- package/src/astro/adapter-root.ts +7 -9
- package/src/astro/component-slots.ts +131 -91
- package/src/astro/generate.ts +114 -345
- package/src/astro/integration.ts +2 -6
- package/src/astro/pages.ts +13 -101
- package/src/astro/render-deps.ts +379 -0
- package/src/astro/runtime-deps.ts +201 -0
- package/src/astro/templates.ts +554 -541
- package/src/audit/agent.ts +24 -0
- package/src/audit/catalog.ts +2 -2
- package/src/audit/checks/assets.ts +2 -2
- package/src/audit/checks/dns-aid.ts +1 -1
- package/src/audit/checks/duplicates.ts +3 -1
- package/src/audit/checks/i18n.ts +1 -1
- package/src/audit/checks/indexability.ts +7 -7
- package/src/audit/checks/links.ts +2 -2
- package/src/audit/checks/llms.ts +6 -6
- package/src/audit/checks/network.ts +3 -3
- package/src/audit/checks/og-image.ts +2 -2
- package/src/audit/checks/robots.ts +1 -1
- package/src/audit/checks/sitemap.ts +2 -2
- package/src/audit/checks/social.ts +1 -1
- package/src/audit/run.ts +4 -3
- package/src/audit/terms.ts +31 -0
- package/src/audit/url.ts +13 -13
- package/src/cli/command-meta.ts +10 -0
- package/src/cli/commands/audit.ts +39 -20
- package/src/cli/commands/build.ts +71 -314
- package/src/cli/commands/check.ts +1 -0
- package/src/cli/commands/dev.ts +40 -1
- package/src/cli/commands/doctor.ts +90 -14
- package/src/cli/commands/eject.ts +44 -7
- package/src/cli/commands/eval.ts +2 -2
- package/src/cli/commands/init.ts +161 -41
- package/src/cli/commands/migrate.ts +121 -0
- package/src/cli/commands/preview.ts +7 -1
- package/src/cli/commands/translate.ts +2 -2
- package/src/cli/commands/upgrade.ts +141 -0
- package/src/cli/commands/version.ts +57 -44
- package/src/cli/eject-scripts.ts +121 -6
- package/src/cli/index.ts +11 -1
- package/src/cli/init/install.ts +70 -0
- package/src/cli/init/questions.ts +7 -0
- package/src/cli/init/scaffold.ts +459 -75
- package/src/cli/lazy-command.ts +37 -1
- package/src/cli/prepare.ts +40 -6
- package/src/cli/required-secrets.ts +38 -11
- package/src/cli/unknown-flags.ts +266 -0
- package/src/cli/yarn-pnp.ts +52 -0
- package/src/components/content/AccordionItem.astro +7 -1
- package/src/components/content/Card.astro +4 -3
- package/src/components/content/ColorItem.astro +22 -4
- package/src/components/content/GithubInfo.astro +2 -2
- package/src/components/content/Prompt.astro +25 -25
- package/src/components/content/Tabs.astro +3 -1
- package/src/components/content/Tile.astro +2 -3
- package/src/components/content/Tooltip.astro +57 -9
- package/src/components/content/content-strings.ts +34 -0
- package/src/components/content/diff.ts +1 -1
- package/src/components/content/mermaid-element.ts +13 -2
- package/src/components/content/prompt-markdown.ts +292 -0
- package/src/components/content/tooltip-id.ts +41 -0
- package/src/components/islands/hooks.ts +75 -3
- package/src/components/layout/Analytics.astro +21 -79
- package/src/components/layout/Banner.astro +3 -1
- package/src/components/layout/DiscoveryLinks.astro +69 -0
- package/src/components/layout/Header.astro +83 -20
- package/src/components/layout/LanguageSwitcher.astro +4 -1
- package/src/components/layout/Logo.astro +23 -2
- package/src/components/layout/NavSelector.astro +13 -2
- package/src/components/layout/NavTree.astro +12 -3
- package/src/components/layout/NavTreeScript.astro +17 -3
- package/src/components/layout/PageActions.astro +3 -3
- package/src/components/layout/PageFeedback.astro +11 -1
- package/src/components/layout/PageLayout.astro +52 -5
- package/src/components/layout/ReferenceLayout.astro +21 -12
- package/src/components/layout/RootLayout.astro +69 -43
- package/src/components/layout/Search.astro +30 -6
- package/src/components/layout/WebMcp.astro +1 -1
- package/src/components/layout/analytics-client.ts +101 -15
- package/src/components/layout/drawer-inert.ts +113 -15
- package/src/components/layout/dropdown-clamp.ts +105 -0
- package/src/components/layout/head-scripts.ts +15 -6
- package/src/components/layout/nav-utils.ts +17 -0
- package/src/components/layout/search/algolia.ts +8 -8
- package/src/components/layout/search/orama-cloud.ts +9 -7
- package/src/components/layout/search/typesense.ts +11 -17
- package/src/components/openapi/MessageComposer.astro +2 -2
- package/src/components/openapi/Playground.astro +2 -2
- package/src/components/openapi/playground-client.ts +79 -10
- package/src/core/changelog-index.ts +24 -0
- package/src/core/component-overrides.ts +399 -154
- package/src/core/config-input.ts +212 -543
- package/src/core/config.ts +130 -41
- package/src/core/custom-pages.ts +105 -0
- package/src/core/data.ts +32 -11
- package/src/core/define-components.ts +12 -9
- package/src/core/deployment-env.ts +18 -74
- package/src/core/diagnostics.ts +14 -7
- package/src/core/graph.ts +69 -25
- package/src/core/i18n-ui.ts +6 -2
- package/src/core/i18n.ts +17 -0
- package/src/core/includes.ts +156 -38
- package/src/core/last-modified.ts +6 -11
- package/src/core/links.ts +166 -2
- package/src/core/manifest.ts +10 -3
- package/src/core/navigation.ts +137 -19
- package/src/core/new-tab.ts +35 -0
- package/src/core/node-require.ts +21 -0
- package/src/core/project-graph.ts +42 -26
- package/src/core/project.ts +9 -4
- package/src/core/request-body.ts +61 -0
- package/src/core/safe-href.ts +28 -0
- package/src/core/safe-links.ts +68 -0
- package/src/core/schema.ts +531 -721
- package/src/core/server-features.ts +8 -9
- package/src/core/sources/assets.ts +47 -11
- package/src/core/sources/collection.ts +67 -0
- package/src/core/sources/contentful-rich-text.ts +285 -0
- package/src/core/sources/contentful.ts +173 -0
- package/src/core/sources/github-releases.ts +51 -1
- package/src/core/sources/json.ts +71 -0
- package/src/core/sources/lexical.ts +195 -0
- package/src/core/sources/lower.ts +226 -0
- package/src/core/sources/normalize.ts +52 -2
- package/src/core/sources/notion.ts +39 -28
- package/src/core/sources/payload.ts +135 -0
- package/src/core/sources/portable-text.ts +11 -16
- package/src/core/sources/remote.ts +226 -0
- package/src/core/sources/resolve.ts +104 -166
- package/src/core/sources/sanity.ts +16 -49
- package/src/core/sources/strapi-blocks.ts +124 -0
- package/src/core/sources/strapi.ts +191 -0
- package/src/core/sources/types.ts +12 -1
- package/src/core/types.ts +20 -1
- package/src/core/ui-packs/ar.ts +6 -2
- package/src/core/ui-packs/bg.ts +6 -2
- package/src/core/ui-packs/bn.ts +6 -2
- package/src/core/ui-packs/ca.ts +3 -1
- package/src/core/ui-packs/cs.ts +6 -2
- package/src/core/ui-packs/da.ts +6 -2
- package/src/core/ui-packs/de.ts +6 -2
- package/src/core/ui-packs/el.ts +3 -1
- package/src/core/ui-packs/es.ts +3 -1
- package/src/core/ui-packs/fa.ts +6 -2
- package/src/core/ui-packs/fi.ts +6 -2
- package/src/core/ui-packs/fr.ts +3 -1
- package/src/core/ui-packs/he.ts +6 -2
- package/src/core/ui-packs/hi.ts +6 -2
- package/src/core/ui-packs/hr.ts +6 -2
- package/src/core/ui-packs/hu.ts +6 -2
- package/src/core/ui-packs/id.ts +6 -2
- package/src/core/ui-packs/it.ts +3 -1
- package/src/core/ui-packs/ja.ts +3 -1
- package/src/core/ui-packs/ko.ts +3 -1
- package/src/core/ui-packs/nl.ts +6 -2
- package/src/core/ui-packs/no.ts +6 -2
- package/src/core/ui-packs/pl.ts +6 -2
- package/src/core/ui-packs/pt-br.ts +3 -1
- package/src/core/ui-packs/pt.ts +3 -1
- package/src/core/ui-packs/ro.ts +6 -2
- package/src/core/ui-packs/ru.ts +6 -2
- package/src/core/ui-packs/sk.ts +6 -2
- package/src/core/ui-packs/sr.ts +6 -2
- package/src/core/ui-packs/sv.ts +6 -2
- package/src/core/ui-packs/th.ts +3 -1
- package/src/core/ui-packs/tr.ts +6 -2
- package/src/core/ui-packs/uk.ts +6 -2
- package/src/core/ui-packs/vi.ts +3 -1
- package/src/core/ui-packs/zh-tw.ts +3 -1
- package/src/core/ui-packs/zh.ts +3 -1
- package/src/core/unrecognized-keys.ts +10 -0
- package/src/core/version-cut.ts +116 -8
- package/src/deploy/adapter-output.ts +57 -97
- package/src/deploy/adapters/cloudflare.ts +39 -0
- package/src/deploy/adapters/index.ts +41 -0
- package/src/deploy/adapters/netlify.ts +34 -0
- package/src/deploy/adapters/node.ts +34 -0
- package/src/deploy/adapters/registry.ts +127 -0
- package/src/deploy/adapters/types.ts +92 -0
- package/src/deploy/adapters/vercel.ts +35 -0
- package/src/deploy/artifacts.ts +67 -28
- package/src/deploy/cloudflare-negotiation.ts +179 -100
- package/src/deploy/function-bundle.ts +18 -3
- package/src/deploy/headers.ts +129 -22
- package/src/deploy/node-headers.ts +198 -0
- package/src/deploy/platforms/cloudflare.ts +312 -0
- package/src/deploy/platforms/index.ts +67 -0
- package/src/deploy/platforms/netlify.ts +52 -0
- package/src/deploy/platforms/node.ts +40 -0
- package/src/deploy/platforms/paths.ts +42 -0
- package/src/deploy/platforms/static.ts +29 -0
- package/src/deploy/platforms/types.ts +112 -0
- package/src/deploy/platforms/vercel.ts +193 -0
- package/src/deploy/redirects.ts +30 -18
- package/src/deploy/robots.ts +3 -3
- package/src/deploy/rss.ts +2 -2
- package/src/deploy/sitemap.ts +2 -2
- package/src/deploy/vercel-negotiation.ts +27 -4
- package/src/eval/agents.ts +32 -1
- package/src/eval/findings.ts +19 -11
- package/src/eval/report.ts +10 -2
- package/src/markdown/external-links.ts +65 -0
- package/src/markdown/include.ts +45 -27
- package/src/markdown/index.ts +34 -9
- package/src/markdown/inline-code.ts +12 -6
- package/src/markdown/relative-links.ts +324 -0
- package/src/markdown/themes.ts +3 -3
- package/src/migrate/migrate.ts +149 -0
- package/src/openapi/parse.ts +64 -16
- package/src/openapi/proxy.ts +62 -10
- package/src/openapi/references.ts +147 -147
- package/src/openapi/render-mdx.ts +32 -10
- package/src/openapi/scalar.ts +15 -13
- package/src/openapi/sentence.ts +14 -0
- package/src/openapi/source.ts +37 -21
- package/src/openapi/spec-dependency-error.ts +15 -0
- package/src/reference/asyncapi.ts +83 -0
- package/src/reference/graphql.ts +89 -0
- package/src/reference/index.ts +40 -0
- package/src/reference/openapi.ts +83 -0
- package/src/reference/options.ts +201 -0
- package/src/reference/scalar.ts +136 -0
- package/src/reference/schema.ts +88 -0
- package/src/registry/eject.ts +97 -42
- package/src/search/adapters/algolia.ts +46 -0
- package/src/search/adapters/flexsearch.ts +29 -0
- package/src/search/adapters/index.ts +39 -0
- package/src/search/adapters/mixedbread.ts +39 -0
- package/src/search/adapters/orama-cloud.ts +51 -0
- package/src/search/adapters/orama.ts +24 -0
- package/src/search/adapters/pagefind.ts +27 -0
- package/src/search/adapters/registry.ts +131 -0
- package/src/search/adapters/types.ts +46 -0
- package/src/search/adapters/typesense.ts +57 -0
- package/src/search/build.ts +33 -7
- package/src/search/documents.ts +6 -0
- package/src/search/sync/algolia.ts +12 -11
- package/src/search/sync/index.ts +35 -20
- package/src/search/sync/orama-cloud.ts +12 -9
- package/src/search/sync/typesense.ts +15 -13
- package/src/sources/contentful.ts +63 -0
- package/src/sources/custom.ts +38 -0
- package/src/sources/filesystem.ts +51 -0
- package/src/sources/github-releases.ts +52 -0
- package/src/sources/index.ts +60 -0
- package/src/sources/mdx-remote.ts +76 -0
- package/src/sources/notion.ts +63 -0
- package/src/sources/obsidian.ts +38 -0
- package/src/sources/payload.ts +60 -0
- package/src/sources/registry.ts +182 -0
- package/src/sources/sanity.ts +66 -0
- package/src/sources/shared.ts +52 -0
- package/src/sources/strapi.ts +58 -0
- package/src/theme/entry.ts +47 -2
- package/src/translate/report.ts +40 -7
- package/src/upgrade/upgrade.ts +499 -0
- package/dist/cli/chunk-12dxjqk7.js.map +0 -10
- package/dist/cli/chunk-196vjxp9.js.map +0 -13
- package/dist/cli/chunk-2mzebbbz.js +0 -69
- package/dist/cli/chunk-2z47ypj8.js.map +0 -11
- package/dist/cli/chunk-30e87n55.js +0 -108
- package/dist/cli/chunk-30e87n55.js.map +0 -10
- package/dist/cli/chunk-450a7rcr.js +0 -185
- package/dist/cli/chunk-450a7rcr.js.map +0 -11
- package/dist/cli/chunk-5n7t497w.js.map +0 -40
- package/dist/cli/chunk-61j18dwk.js +0 -5342
- package/dist/cli/chunk-61j18dwk.js.map +0 -58
- package/dist/cli/chunk-88by27n5.js +0 -17
- package/dist/cli/chunk-88by27n5.js.map +0 -10
- package/dist/cli/chunk-8cd8tj54.js.map +0 -34
- package/dist/cli/chunk-aztttvb3.js +0 -381
- package/dist/cli/chunk-aztttvb3.js.map +0 -12
- package/dist/cli/chunk-cvky9gb2.js.map +0 -11
- package/dist/cli/chunk-ejjx8znq.js.map +0 -15
- package/dist/cli/chunk-fmceyezb.js +0 -1007
- package/dist/cli/chunk-fmceyezb.js.map +0 -13
- package/dist/cli/chunk-hdm2dkd2.js.map +0 -48
- package/dist/cli/chunk-hs3gbh8p.js.map +0 -10
- package/dist/cli/chunk-jbj4qhfw.js +0 -30
- package/dist/cli/chunk-jbj4qhfw.js.map +0 -10
- package/dist/cli/chunk-mqb2ka8m.js +0 -68
- package/dist/cli/chunk-mqb2ka8m.js.map +0 -10
- package/dist/cli/chunk-mt76t7dj.js.map +0 -11
- package/dist/cli/chunk-q4rae3bg.js +0 -60
- package/dist/cli/chunk-q4rae3bg.js.map +0 -10
- package/dist/cli/chunk-ra1v2nc2.js +0 -35
- package/dist/cli/chunk-ra1v2nc2.js.map +0 -10
- package/dist/cli/chunk-t3tj0dgr.js.map +0 -15
- package/dist/cli/chunk-tqa1s0k8.js +0 -69
- package/dist/cli/chunk-tqa1s0k8.js.map +0 -11
- package/dist/cli/chunk-vh9w1sgp.js +0 -73
- package/dist/cli/chunk-vh9w1sgp.js.map +0 -10
- package/dist/cli/chunk-vkrsvbr5.js +0 -107
- package/dist/cli/chunk-vkrsvbr5.js.map +0 -11
- package/dist/cli/chunk-vrfp10qk.js +0 -81
- package/dist/cli/chunk-vrfp10qk.js.map +0 -10
- package/dist/cli/chunk-wjt80jps.js +0 -1049
- package/dist/cli/chunk-wjt80jps.js.map +0 -24
- package/docs/advanced/api-reference.mdx +0 -240
- package/docs/reference/cli.mdx +0 -197
- package/skills/blume-migrate/assets/oxfmt@0.55.0.patch +0 -20
- package/src/components/content/changelog-element.ts +0 -69
- package/src/search/providers.ts +0 -91
- /package/dist/cli/{chunk-3w7b2vcx.js.map → chunk-7ez8ny0t.js.map} +0 -0
- /package/dist/cli/{chunk-688e0dde.js.map → chunk-88cpgt6h.js.map} +0 -0
- /package/dist/cli/{chunk-exeeb35e.js.map → chunk-f7t03s3g.js.map} +0 -0
- /package/dist/cli/{chunk-ppfvdcd4.js.map → chunk-zxccj738.js.map} +0 -0
|
@@ -84,8 +84,11 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
84
84
|
>
|
|
85
85
|
<Icon name="search" size={16} />
|
|
86
86
|
<span class="flex-1 text-start max-lg:hidden">{s.button}</span>
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
{/* A key chord reads left to right in every locale ("⌘K", never "K⌘"). */}
|
|
88
|
+
<kbd
|
|
89
|
+
class="font-mono text-[0.7rem] max-lg:hidden"
|
|
90
|
+
data-blume-search-kbd
|
|
91
|
+
dir="ltr">⌘K</kbd
|
|
89
92
|
>
|
|
90
93
|
</button>
|
|
91
94
|
|
|
@@ -195,8 +198,10 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
195
198
|
{s.open}
|
|
196
199
|
</span>
|
|
197
200
|
<span class="flex items-center gap-1 max-md:hidden">
|
|
198
|
-
<kbd
|
|
199
|
-
|
|
201
|
+
<kbd
|
|
202
|
+
class={`${kbd} text-[0.65rem]`}
|
|
203
|
+
data-blume-search-preview-kbd
|
|
204
|
+
dir="ltr">⌘J</kbd
|
|
200
205
|
>
|
|
201
206
|
{s.preview}
|
|
202
207
|
</span>
|
|
@@ -271,6 +276,26 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
271
276
|
}
|
|
272
277
|
};
|
|
273
278
|
|
|
279
|
+
// The generated client and the index it fetches are the same on every
|
|
280
|
+
// page (locale and version filters apply per query), but each client-router
|
|
281
|
+
// swap rebuilds the header, and this element with it. Loading once in
|
|
282
|
+
// module scope — bundled modules survive swaps — keeps the first search
|
|
283
|
+
// after a navigation from refetching the index and rebuilding it. A failed
|
|
284
|
+
// load clears the cache, so the next open retries.
|
|
285
|
+
let searchClient: Promise<SearchFn> | undefined;
|
|
286
|
+
const loadSearchClient = (): Promise<SearchFn> => {
|
|
287
|
+
searchClient ??= (async () => {
|
|
288
|
+
try {
|
|
289
|
+
const { createSearch } = await import("blume:search-client");
|
|
290
|
+
return await createSearch();
|
|
291
|
+
} catch (error) {
|
|
292
|
+
searchClient = undefined;
|
|
293
|
+
throw error;
|
|
294
|
+
}
|
|
295
|
+
})();
|
|
296
|
+
return searchClient;
|
|
297
|
+
};
|
|
298
|
+
|
|
274
299
|
class BlumeSearch extends HTMLElement {
|
|
275
300
|
dialog!: HTMLDialogElement;
|
|
276
301
|
input!: HTMLInputElement;
|
|
@@ -481,8 +506,7 @@ const kbd = "rounded border border-border bg-muted px-1 py-0.5 font-mono";
|
|
|
481
506
|
if (!this.loaded) {
|
|
482
507
|
this.loading = true;
|
|
483
508
|
try {
|
|
484
|
-
|
|
485
|
-
this.searchFn = await createSearch();
|
|
509
|
+
this.searchFn = await loadSearchClient();
|
|
486
510
|
// Only latch on success — a transient failure (flaky network
|
|
487
511
|
// fetching the index) must retry on the next open, not disable
|
|
488
512
|
// search until a full page reload.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// WebMCP: expose the docs' read-only tools (search, page Markdown, the docs
|
|
3
3
|
// index) to agentic browsers via the page's model context. Rendered by
|
|
4
4
|
// PageLayout on every page; the marker element below both gates the script
|
|
5
|
-
// (absent when `
|
|
5
|
+
// (absent when `agents.webmcp` is off, so it returns immediately) and carries the
|
|
6
6
|
// two config flags the client needs — importing `blume:data` from the client
|
|
7
7
|
// script would drag the whole navigation snapshot into the bundle.
|
|
8
8
|
import data from "blume:data";
|
|
@@ -1,25 +1,108 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Send a custom analytics event to every analytics platform configured in
|
|
3
|
-
* `blume.config.ts`. Mirrors the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
3
|
+
* `blume.config.ts`. Mirrors the adapters `Analytics.astro` wires
|
|
4
|
+
* (`src/analytics/*`): each one with a custom-event API is called through the
|
|
5
|
+
* global its snippet defines (Cloudflare and Clearbit have none to forward
|
|
6
|
+
* to), and the `blume:track` CustomEvent fires unconditionally so a project
|
|
7
|
+
* can bridge the event to anything else — a `script()` adapter, say. Every
|
|
8
|
+
* call no-ops cleanly when a provider isn't present — for example during
|
|
9
|
+
* `blume dev`, where `Analytics.astro` injects nothing — and a provider that
|
|
10
|
+
* throws (a consent shim that stubs `gtag` with a raise, a broken snippet) is
|
|
11
|
+
* isolated so it neither starves the providers after it nor surfaces in the
|
|
12
|
+
* feature that reported the event.
|
|
10
13
|
*/
|
|
11
14
|
import { track as vercelTrack } from "@vercel/analytics";
|
|
12
15
|
|
|
13
16
|
/** Flat, serializable event properties. */
|
|
14
17
|
export type TrackProps = Record<string, boolean | number | string>;
|
|
15
18
|
|
|
19
|
+
/** A Tag Manager data layer: a queue the container drains. */
|
|
20
|
+
interface DataLayer {
|
|
21
|
+
push: (entry: TrackProps & { event: string }) => number;
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
interface AnalyticsWindow {
|
|
25
|
+
/** The data layer a `googleTagManager()` snippet's container reads. */
|
|
26
|
+
__blumeGtmLayer?: DataLayer;
|
|
27
|
+
_satellite?: { track?: (event: string, props?: TrackProps) => void };
|
|
28
|
+
amplitude?: { track?: (event: string, props?: TrackProps) => void };
|
|
29
|
+
analytics?: { track?: (event: string, props?: TrackProps) => void };
|
|
30
|
+
clarity?: (command: "event", event: string) => void;
|
|
31
|
+
dataLayer?: DataLayer;
|
|
32
|
+
fathom?: { trackEvent?: (event: string) => void };
|
|
17
33
|
gtag?: (command: "event", event: string, props?: TrackProps) => void;
|
|
34
|
+
heap?: { track?: (event: string, props?: TrackProps) => void };
|
|
35
|
+
hj?: (command: "event", event: string) => void;
|
|
36
|
+
htevents?: { track?: (event: string, props?: TrackProps) => void };
|
|
37
|
+
LogRocket?: { track?: (event: string, props?: TrackProps) => void };
|
|
38
|
+
mixpanel?: { track?: (event: string, props?: TrackProps) => void };
|
|
39
|
+
pirsch?: (event: string, options?: { meta?: TrackProps }) => void;
|
|
18
40
|
plausible?: (event: string, options?: { props?: TrackProps }) => void;
|
|
19
41
|
posthog?: { capture?: (event: string, props?: TrackProps) => void };
|
|
20
42
|
}
|
|
21
43
|
|
|
22
|
-
|
|
44
|
+
/** Run one provider call; its failure must not reach the others or the caller. */
|
|
45
|
+
const attempt = (send: () => void): void => {
|
|
46
|
+
try {
|
|
47
|
+
send();
|
|
48
|
+
} catch {
|
|
49
|
+
// Analytics never breaks the feature that reported the event.
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// The SDKs whose loader stub queues calls until the library lands, so the
|
|
54
|
+
// method is there to call from the first paint on.
|
|
55
|
+
const trackQueued = (
|
|
56
|
+
w: AnalyticsWindow,
|
|
57
|
+
event: string,
|
|
58
|
+
props: TrackProps
|
|
59
|
+
): void => {
|
|
60
|
+
attempt(() => w.posthog?.capture?.(event, props));
|
|
61
|
+
attempt(() => w.mixpanel?.track?.(event, props));
|
|
62
|
+
attempt(() => w.heap?.track?.(event, props));
|
|
63
|
+
attempt(() => w.analytics?.track?.(event, props));
|
|
64
|
+
attempt(() => w.htevents?.track?.(event, props));
|
|
65
|
+
attempt(() => w.amplitude?.track?.(event, props));
|
|
66
|
+
attempt(() => w.LogRocket?.track?.(event, props));
|
|
67
|
+
attempt(() => w._satellite?.track?.(event, props));
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// The providers reached through a global function or a data layer rather
|
|
71
|
+
// than a queued SDK object.
|
|
72
|
+
const trackGlobals = (
|
|
73
|
+
w: AnalyticsWindow,
|
|
74
|
+
event: string,
|
|
75
|
+
props: TrackProps
|
|
76
|
+
): void => {
|
|
77
|
+
// Google: `gtag('event')` for the Google tag, and a plain `{ event }` push
|
|
78
|
+
// for a Tag Manager custom-event trigger, into the container's own data
|
|
79
|
+
// layer. Each reads only its own shape, so a site with both configured
|
|
80
|
+
// still sees the event once per product.
|
|
81
|
+
attempt(() => w.gtag?.("event", event, props));
|
|
82
|
+
attempt(() => (w.__blumeGtmLayer ?? w.dataLayer)?.push({ ...props, event }));
|
|
83
|
+
// Privacy-first counters take a name, some with properties.
|
|
84
|
+
attempt(() => w.plausible?.(event, { props }));
|
|
85
|
+
attempt(() => w.fathom?.trackEvent?.(event));
|
|
86
|
+
// Pirsch stringifies `meta` values in place, so it gets its own copy and
|
|
87
|
+
// the `blume:track` listeners still see the original types.
|
|
88
|
+
attempt(() => w.pirsch?.(event, { meta: { ...props } }));
|
|
89
|
+
// Behavior tools take a bare name.
|
|
90
|
+
attempt(() => w.clarity?.("event", event));
|
|
91
|
+
attempt(() => w.hj?.("event", event));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @param event The event name.
|
|
96
|
+
* @param props Properties every provider receives.
|
|
97
|
+
* @param local Properties only the `blume:track` CustomEvent carries — free
|
|
98
|
+
* text a site may bridge to a provider on its own terms, but that must not
|
|
99
|
+
* reach third parties unasked (a reader's Ask AI question, for instance).
|
|
100
|
+
*/
|
|
101
|
+
export const track = (
|
|
102
|
+
event: string,
|
|
103
|
+
props: TrackProps,
|
|
104
|
+
local: TrackProps = {}
|
|
105
|
+
): void => {
|
|
23
106
|
// Read through `globalThis` so an SSR/import-time call sees `undefined`
|
|
24
107
|
// instead of a bare-identifier ReferenceError.
|
|
25
108
|
const browserWindow = globalThis.window;
|
|
@@ -31,12 +114,15 @@ export const track = (event: string, props: TrackProps): void => {
|
|
|
31
114
|
const w = browserWindow as typeof browserWindow & AnalyticsWindow;
|
|
32
115
|
|
|
33
116
|
// Vercel Web Analytics — self-gates to a no-op until `window.va` is set up.
|
|
34
|
-
vercelTrack(event, props);
|
|
35
|
-
|
|
36
|
-
w
|
|
37
|
-
// Popular providers wired through `analytics.scripts` (GA4/GTM, Plausible).
|
|
38
|
-
w.gtag?.("event", event, props);
|
|
39
|
-
w.plausible?.(event, { props });
|
|
117
|
+
attempt(() => vercelTrack(event, props));
|
|
118
|
+
trackQueued(w, event, props);
|
|
119
|
+
trackGlobals(w, event, props);
|
|
40
120
|
// Universal hook for any other integration.
|
|
41
|
-
|
|
121
|
+
attempt(() =>
|
|
122
|
+
w.dispatchEvent(
|
|
123
|
+
new CustomEvent("blume:track", {
|
|
124
|
+
detail: { event, props: { ...props, ...local } },
|
|
125
|
+
})
|
|
126
|
+
)
|
|
127
|
+
);
|
|
42
128
|
};
|
|
@@ -1,36 +1,134 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
2
|
+
* The mobile nav drawer's accessibility. The header's click script opens and
|
|
3
|
+
* closes the drawer by toggling `data-blume-nav-open` on `<html>`; everything
|
|
4
|
+
* here follows that attribute, only below `lg` (64rem) — at `lg` and up the same
|
|
5
|
+
* element is the static sidebar (RootLayout) or display-hidden (PageLayout):
|
|
6
|
+
*
|
|
7
|
+
* - Closed, the drawer is only translated off-canvas, so its links would stay
|
|
8
|
+
* focusable on every page: it's `inert`/`aria-hidden` instead.
|
|
9
|
+
* - Open, it's a modal panel over the page: the page behind it (everything but
|
|
10
|
+
* the header, which holds the toggle, and the overlay button) goes `inert`,
|
|
11
|
+
* so Tab can't wander into content the overlay covers, and the header's
|
|
12
|
+
* toggle reports `aria-expanded`.
|
|
13
|
+
* - Escape closes it, and closing it with focus inside (or on the overlay's
|
|
14
|
+
* close button, which disappears) returns focus to the toggle.
|
|
15
|
+
*
|
|
16
|
+
* Shared by both layouts' bundled scripts, which run once per real page load;
|
|
17
|
+
* the drawer and the page behind it are rebuilt by every client-router swap, so
|
|
18
|
+
* `sync` re-queries them each time and re-runs on `astro:after-swap`.
|
|
10
19
|
*/
|
|
20
|
+
|
|
21
|
+
const OPEN_ATTRIBUTE = "data-blume-nav-open";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Marks what `sync` made inert behind the open drawer, so closing it restores
|
|
25
|
+
* only those — never an element something else made inert.
|
|
26
|
+
*/
|
|
27
|
+
const BACKDROP_ATTRIBUTE = "data-blume-drawer-backdrop";
|
|
28
|
+
|
|
29
|
+
/** What stays live beside the open drawer: the header and the overlay. */
|
|
30
|
+
const KEEP_LIVE =
|
|
31
|
+
"[data-blume-header], [data-blume-nav-toggle], script, style, template";
|
|
32
|
+
|
|
33
|
+
const drawerElement = (): HTMLElement | null =>
|
|
34
|
+
document.querySelector<HTMLElement>("[data-blume-nav-drawer]");
|
|
35
|
+
|
|
36
|
+
const headerToggle = (): HTMLElement | null =>
|
|
37
|
+
document.querySelector<HTMLElement>(
|
|
38
|
+
"[data-blume-header] [data-blume-nav-toggle]"
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The page behind the drawer: every sibling along the drawer's path up to
|
|
43
|
+
* `<body>`, minus what stays live.
|
|
44
|
+
*/
|
|
45
|
+
const backdropOf = (drawer: Element): Element[] => {
|
|
46
|
+
const backdrop: Element[] = [];
|
|
47
|
+
let node = drawer;
|
|
48
|
+
while (node !== document.body && node.parentElement) {
|
|
49
|
+
for (const sibling of node.parentElement.children) {
|
|
50
|
+
if (sibling !== node && !sibling.matches(KEEP_LIVE)) {
|
|
51
|
+
backdrop.push(sibling);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
node = node.parentElement;
|
|
55
|
+
}
|
|
56
|
+
return backdrop;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const restoreBackdrop = (): void => {
|
|
60
|
+
for (const element of document.querySelectorAll(`[${BACKDROP_ATTRIBUTE}]`)) {
|
|
61
|
+
element.removeAttribute("inert");
|
|
62
|
+
element.removeAttribute(BACKDROP_ATTRIBUTE);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const inertBackdrop = (drawer: Element): void => {
|
|
67
|
+
for (const element of backdropOf(drawer)) {
|
|
68
|
+
// Already inert for another reason: leave it, and leave it unmarked.
|
|
69
|
+
if (!element.hasAttribute("inert")) {
|
|
70
|
+
element.setAttribute("inert", "");
|
|
71
|
+
element.setAttribute(BACKDROP_ATTRIBUTE, "");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
11
76
|
export const syncDrawerInert = (): void => {
|
|
12
77
|
const desktop = window.matchMedia("(min-width: 64rem)");
|
|
78
|
+
const isOpen = () =>
|
|
79
|
+
!desktop.matches && document.documentElement.hasAttribute(OPEN_ATTRIBUTE);
|
|
80
|
+
let wasOpen = false;
|
|
81
|
+
|
|
13
82
|
const sync = () => {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
);
|
|
83
|
+
const open = isOpen();
|
|
84
|
+
headerToggle()?.setAttribute("aria-expanded", open ? "true" : "false");
|
|
85
|
+
const drawer = drawerElement();
|
|
17
86
|
if (!drawer) {
|
|
87
|
+
restoreBackdrop();
|
|
88
|
+
wasOpen = open;
|
|
18
89
|
return;
|
|
19
90
|
}
|
|
20
|
-
const hidden =
|
|
21
|
-
!desktop.matches &&
|
|
22
|
-
!Object.hasOwn(document.documentElement.dataset, "blumeNavOpen");
|
|
91
|
+
const hidden = !(desktop.matches || open);
|
|
23
92
|
drawer.inert = hidden;
|
|
24
93
|
if (hidden) {
|
|
25
94
|
drawer.setAttribute("aria-hidden", "true");
|
|
26
95
|
} else {
|
|
27
96
|
drawer.removeAttribute("aria-hidden");
|
|
28
97
|
}
|
|
98
|
+
if (open) {
|
|
99
|
+
inertBackdrop(drawer);
|
|
100
|
+
} else {
|
|
101
|
+
restoreBackdrop();
|
|
102
|
+
const active = document.activeElement;
|
|
103
|
+
if (
|
|
104
|
+
wasOpen &&
|
|
105
|
+
!desktop.matches &&
|
|
106
|
+
active &&
|
|
107
|
+
(drawer.contains(active) || active.matches("[data-blume-nav-toggle]"))
|
|
108
|
+
) {
|
|
109
|
+
headerToggle()?.focus();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
wasOpen = open;
|
|
29
113
|
};
|
|
114
|
+
|
|
30
115
|
sync();
|
|
31
116
|
desktop.addEventListener("change", sync);
|
|
32
117
|
new MutationObserver(sync).observe(document.documentElement, {
|
|
33
|
-
attributeFilter: [
|
|
118
|
+
attributeFilter: [OPEN_ATTRIBUTE],
|
|
34
119
|
});
|
|
35
120
|
document.addEventListener("astro:after-swap", sync);
|
|
121
|
+
document.addEventListener("keydown", (event) => {
|
|
122
|
+
// An open dialog (search, Ask AI) closes itself on Escape first.
|
|
123
|
+
if (
|
|
124
|
+
event.key !== "Escape" ||
|
|
125
|
+
!isOpen() ||
|
|
126
|
+
document.querySelector("dialog[open]")
|
|
127
|
+
) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
document.documentElement.removeAttribute(OPEN_ATTRIBUTE);
|
|
131
|
+
sync();
|
|
132
|
+
headerToggle()?.focus();
|
|
133
|
+
});
|
|
36
134
|
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep a header selector's dropdown panel inside the viewport. The panel is
|
|
3
|
+
* absolutely positioned against its trigger (`end-0` for the version
|
|
4
|
+
* selector), which is right on desktop, where the trigger sits at the header's
|
|
5
|
+
* trailing edge — but on a phone the trigger lands mid-header, so a 14rem
|
|
6
|
+
* panel anchored to its end runs off the leading edge (and, mirrored, off the
|
|
7
|
+
* trailing edge in a right-to-left locale). When a panel opens, it is measured
|
|
8
|
+
* and nudged back inside with `translate`, which leaves the anchoring classes
|
|
9
|
+
* — and the desktop layout — untouched.
|
|
10
|
+
*
|
|
11
|
+
* One capture-phase `toggle` listener on `document` (the event doesn't bubble)
|
|
12
|
+
* serves every opted-in dropdown, installed once per real page load: the
|
|
13
|
+
* client router rebuilds the header markup on each swap, and delegation needs
|
|
14
|
+
* no re-binding.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Gap kept between a clamped panel and the viewport edge, in pixels. */
|
|
18
|
+
const MARGIN = 8;
|
|
19
|
+
|
|
20
|
+
/** The panel an opted-in `<details>` dropdown clamps. */
|
|
21
|
+
export const CLAMPED_PANEL = "[data-blume-dropdown-panel]";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The horizontal shift that brings a panel spanning `left`…`right` inside a
|
|
25
|
+
* viewport `width` wide, keeping `margin` at each edge. A panel wider than the
|
|
26
|
+
* room available pins its leading edge (the one reading starts from) to the
|
|
27
|
+
* margin.
|
|
28
|
+
*/
|
|
29
|
+
export const clampShift = (
|
|
30
|
+
left: number,
|
|
31
|
+
right: number,
|
|
32
|
+
width: number,
|
|
33
|
+
rtl: boolean,
|
|
34
|
+
margin = MARGIN
|
|
35
|
+
): number => {
|
|
36
|
+
const tooWide = right - left > width - 2 * margin;
|
|
37
|
+
if (tooWide) {
|
|
38
|
+
return rtl ? width - margin - right : margin - left;
|
|
39
|
+
}
|
|
40
|
+
if (left < margin) {
|
|
41
|
+
return margin - left;
|
|
42
|
+
}
|
|
43
|
+
if (right > width - margin) {
|
|
44
|
+
return width - margin - right;
|
|
45
|
+
}
|
|
46
|
+
return 0;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** The slice of a panel element the clamp measures and moves. */
|
|
50
|
+
export interface PanelBox {
|
|
51
|
+
getBoundingClientRect: () => { left: number; right: number };
|
|
52
|
+
style: { translate: string };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Measure `panel` in place and shift it back inside the viewport. */
|
|
56
|
+
export const clampPanel = (panel: PanelBox): void => {
|
|
57
|
+
panel.style.translate = "";
|
|
58
|
+
const { left, right } = panel.getBoundingClientRect();
|
|
59
|
+
const root = document.documentElement;
|
|
60
|
+
const shift = clampShift(
|
|
61
|
+
left,
|
|
62
|
+
right,
|
|
63
|
+
root.clientWidth,
|
|
64
|
+
root.getAttribute("dir") === "rtl"
|
|
65
|
+
);
|
|
66
|
+
if (shift !== 0) {
|
|
67
|
+
panel.style.translate = `${shift}px 0`;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/** The clamped panel of the dropdown a `toggle` event opened, if any. */
|
|
72
|
+
const openedPanel = (target: EventTarget | null): HTMLElement | null =>
|
|
73
|
+
target instanceof HTMLDetailsElement && target.open
|
|
74
|
+
? target.querySelector<HTMLElement>(CLAMPED_PANEL)
|
|
75
|
+
: null;
|
|
76
|
+
|
|
77
|
+
/** Clamp every open panel again, after the viewport changed size. */
|
|
78
|
+
const reclampOpen = (): void => {
|
|
79
|
+
for (const panel of document.querySelectorAll<HTMLElement>(
|
|
80
|
+
`details[open] > ${CLAMPED_PANEL}`
|
|
81
|
+
)) {
|
|
82
|
+
clampPanel(panel);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
let installed = false;
|
|
87
|
+
|
|
88
|
+
/** Clamp opted-in dropdown panels on open (and on resize while open). */
|
|
89
|
+
export const installDropdownClamp = (): void => {
|
|
90
|
+
if (installed) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
installed = true;
|
|
94
|
+
document.addEventListener(
|
|
95
|
+
"toggle",
|
|
96
|
+
(event) => {
|
|
97
|
+
const panel = openedPanel(event.target);
|
|
98
|
+
if (panel) {
|
|
99
|
+
clampPanel(panel);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
true
|
|
103
|
+
);
|
|
104
|
+
window.addEventListener("resize", reclampOpen);
|
|
105
|
+
};
|
|
@@ -39,9 +39,13 @@
|
|
|
39
39
|
* the `after-swap` re-apply stays as the fallback that also picks up a
|
|
40
40
|
* preference changed in another tab.
|
|
41
41
|
*
|
|
42
|
-
* Reads `data-mode` — `"system" | "light" | "dark"`.
|
|
42
|
+
* Reads `data-mode` — `"system" | "light" | "dark"`. Blocked storage (Safari
|
|
43
|
+
* "Block All Cookies", sandboxed iframes) throws on read. That reads as no
|
|
44
|
+
* stored preference instead of aborting before the swap listeners exist, and
|
|
45
|
+
* after a swap the theme the `before-swap` stamp carried over stands, so a
|
|
46
|
+
* toggle the reader made still holds for the rest of their visit.
|
|
43
47
|
*/
|
|
44
|
-
export const THEME_INIT_SCRIPT = `(()=>{const m=document.currentScript?.dataset.mode??"system";const apply=()=>{const s=localStorage.getItem("blume-theme");const sys=matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";
|
|
48
|
+
export const THEME_INIT_SCRIPT = `(()=>{const m=document.currentScript?.dataset.mode??"system";const apply=()=>{const r=document.documentElement;let s=null;let blocked=false;try{s=localStorage.getItem("blume-theme");}catch{blocked=true;}const sys=matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";r.dataset.theme=s??(blocked&&r.dataset.theme?r.dataset.theme:m==="system"?sys:m);};apply();document.addEventListener("astro:before-swap",(e)=>{const t=document.documentElement.dataset.theme;if(t){e.newDocument.documentElement.dataset.theme=t;}});document.addEventListener("astro:after-swap",apply);})();`;
|
|
45
49
|
|
|
46
50
|
/**
|
|
47
51
|
* Keep an embedded Scalar reference on Blume's theme. Scalar picks its own
|
|
@@ -63,12 +67,17 @@ export const THEME_INIT_SCRIPT = `(()=>{const m=document.currentScript?.dataset.
|
|
|
63
67
|
export const SCALAR_THEME_INIT_SCRIPT = `(()=>{const d=document.documentElement;const mode=()=>d.dataset.theme==="dark"?"dark":"light";let pinned=0;for(const el of document.querySelectorAll("[data-scalar-client]")){let c;try{c=JSON.parse(el.dataset.configuration||"{}");}catch{continue;}if("forceDarkModeState" in c||"darkMode" in c){continue;}c.forceDarkModeState=mode();el.dataset.configuration=JSON.stringify(c);pinned+=1;}if(!pinned){return;}new MutationObserver(()=>{const dark=mode()==="dark";document.body.classList.toggle("dark-mode",dark);document.body.classList.toggle("light-mode",!dark);}).observe(d,{attributes:true,attributeFilter:["data-theme"]});})();`;
|
|
64
68
|
|
|
65
69
|
/**
|
|
66
|
-
* Hide a previously-dismissed banner before it can flash in — and
|
|
67
|
-
*
|
|
70
|
+
* Hide a previously-dismissed banner before it can flash in — and keep it
|
|
71
|
+
* hidden across client-router swaps, which replace the `<html>` attributes with
|
|
72
|
+
* the incoming page's: `astro:before-swap` carries the marker onto the incoming
|
|
73
|
+
* root (as the theme script does with `data-theme`), and `after-swap` re-reads
|
|
74
|
+
* storage as the fallback.
|
|
68
75
|
*
|
|
69
|
-
* Reads `data-key` — the banner's dismissal key.
|
|
76
|
+
* Reads `data-key` — the banner's dismissal key. A storage read that throws
|
|
77
|
+
* (blocked storage) reads as not dismissed; a dismissal made on this visit
|
|
78
|
+
* still holds across its swaps through the carried-over marker.
|
|
70
79
|
*/
|
|
71
|
-
export const BANNER_INIT_SCRIPT = `(()=>{const k=document.currentScript?.dataset.key;if(!k){return;}const apply=()=>{
|
|
80
|
+
export const BANNER_INIT_SCRIPT = `(()=>{const k=document.currentScript?.dataset.key;if(!k){return;}const apply=()=>{let hidden=null;try{hidden=localStorage.getItem("blume-banner:"+k);}catch{}if(hidden){document.documentElement.setAttribute("data-blume-banner-hidden","");}};apply();document.addEventListener("astro:before-swap",(e)=>{if(document.documentElement.hasAttribute("data-blume-banner-hidden")){e.newDocument.documentElement.setAttribute("data-blume-banner-hidden","");}});document.addEventListener("astro:after-swap",apply);})();`;
|
|
72
81
|
|
|
73
82
|
/**
|
|
74
83
|
* Keep the page styled across client-router swaps. Astro hoists the CSS of a
|
|
@@ -14,6 +14,23 @@ export interface Crumb {
|
|
|
14
14
|
route?: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Whether a group's header row reads as the current page. A routed group links
|
|
19
|
+
* to its folder's index page; when that index is also listed as one of the
|
|
20
|
+
* group's own rows (kept under a different label), the row is the more
|
|
21
|
+
* specific indicator, so the header stays quiet rather than lighting up beside
|
|
22
|
+
* it. With the index row hidden the header is the only link and takes the
|
|
23
|
+
* highlight.
|
|
24
|
+
*/
|
|
25
|
+
export const isGroupRowCurrent = (
|
|
26
|
+
group: Extract<NavNode, { kind: "group" }>,
|
|
27
|
+
currentRoute: string
|
|
28
|
+
): boolean =>
|
|
29
|
+
group.route === currentRoute &&
|
|
30
|
+
!group.children.some(
|
|
31
|
+
(child) => child.kind === "page" && child.route === currentRoute
|
|
32
|
+
);
|
|
33
|
+
|
|
17
34
|
/** Flatten the sidebar tree into ordered internal page links. */
|
|
18
35
|
export const flattenPages = (nodes: NavNode[]): FlatPage[] => {
|
|
19
36
|
const out: FlatPage[] = [];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { liteClient } from "algoliasearch/lite";
|
|
2
2
|
|
|
3
|
+
import type { AlgoliaOptions } from "../../../search/adapters/algolia.ts";
|
|
3
4
|
import { excerptFor, highlight, SEARCH_LIMIT } from "./types.ts";
|
|
4
5
|
import type { SearchFn } from "./types.ts";
|
|
5
6
|
|
|
@@ -13,20 +14,19 @@ interface AlgoliaRecord {
|
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Algolia: the browser queries the index directly with the public,
|
|
16
|
-
* search-only key. Records are uploaded at build time by the sync step.
|
|
17
|
+
* search-only key. Records are uploaded at build time by the sync step. Every
|
|
18
|
+
* adapter option Blume doesn't read (`hosts`, `timeouts`, `baseHeaders`, …) is
|
|
19
|
+
* the site's own client option and goes to `liteClient` untouched.
|
|
17
20
|
*/
|
|
18
|
-
export const createSearch = (opts: {
|
|
19
|
-
appId
|
|
20
|
-
|
|
21
|
-
searchApiKey: string;
|
|
22
|
-
}): SearchFn => {
|
|
23
|
-
const client = liteClient(opts.appId, opts.searchApiKey);
|
|
21
|
+
export const createSearch = (opts: AlgoliaOptions): SearchFn => {
|
|
22
|
+
const { apiKey, appId, indexName, ...clientOptions } = opts;
|
|
23
|
+
const client = liteClient(appId, apiKey, clientOptions);
|
|
24
24
|
return async (query, options) => {
|
|
25
25
|
const { results } = await client.search<AlgoliaRecord>({
|
|
26
26
|
requests: [
|
|
27
27
|
{
|
|
28
28
|
hitsPerPage: SEARCH_LIMIT,
|
|
29
|
-
indexName
|
|
29
|
+
indexName,
|
|
30
30
|
query,
|
|
31
31
|
// The sync uploads `locale` and `version` on every record so a
|
|
32
32
|
// site can scope hosted results to the active language and the
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OramaClient } from "@oramacloud/client";
|
|
2
2
|
|
|
3
|
+
import type { OramaCloudOptions } from "../../../search/adapters/orama-cloud.ts";
|
|
3
4
|
import { excerptFor, highlight, SEARCH_LIMIT } from "./types.ts";
|
|
4
5
|
import type { SearchFn } from "./types.ts";
|
|
5
6
|
|
|
@@ -12,15 +13,16 @@ interface OramaCloudRecord {
|
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Orama Cloud: the browser queries the hosted index directly with the public
|
|
15
|
-
* endpoint + API key. Records are pushed at build time by the sync step.
|
|
16
|
+
* endpoint + API key. Records are pushed at build time by the sync step. Every
|
|
17
|
+
* adapter option Blume doesn't read is the site's own client option and goes
|
|
18
|
+
* to `OramaClient` untouched; `indexId` belongs to the sync and stays out.
|
|
16
19
|
*/
|
|
17
|
-
export const createSearch = (opts: {
|
|
18
|
-
endpoint:
|
|
19
|
-
apiKey: string;
|
|
20
|
-
}): SearchFn => {
|
|
20
|
+
export const createSearch = (opts: OramaCloudOptions): SearchFn => {
|
|
21
|
+
const { apiKey, endpoint, indexId: _syncOnly, ...clientOptions } = opts;
|
|
21
22
|
const client = new OramaClient({
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
...clientOptions,
|
|
24
|
+
api_key: apiKey,
|
|
25
|
+
endpoint,
|
|
24
26
|
});
|
|
25
27
|
return async (query, options) => {
|
|
26
28
|
const results = await client.search({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Client } from "typesense";
|
|
2
2
|
|
|
3
|
+
import type { TypesenseOptions } from "../../../search/adapters/typesense.ts";
|
|
3
4
|
import { excerptFor, highlight, SEARCH_LIMIT } from "./types.ts";
|
|
4
5
|
import type { SearchFn } from "./types.ts";
|
|
5
6
|
|
|
@@ -13,28 +14,21 @@ interface TypesenseRecord extends Record<string, unknown> {
|
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Typesense: the browser queries the collection directly with the search-only
|
|
16
|
-
* key. Documents are imported at build time by the sync step.
|
|
17
|
+
* key. Documents are imported at build time by the sync step. Every adapter
|
|
18
|
+
* option Blume doesn't read (`connectionTimeoutSeconds`, `numRetries`, …) is
|
|
19
|
+
* the site's own client option and goes to the `Client` untouched; the named
|
|
20
|
+
* connection options still decide `apiKey` and `nodes`.
|
|
17
21
|
*/
|
|
18
|
-
export const createSearch = (opts: {
|
|
19
|
-
collection
|
|
20
|
-
host: string;
|
|
21
|
-
port?: number;
|
|
22
|
-
protocol?: string;
|
|
23
|
-
searchApiKey: string;
|
|
24
|
-
}): SearchFn => {
|
|
22
|
+
export const createSearch = (opts: TypesenseOptions): SearchFn => {
|
|
23
|
+
const { apiKey, collection, host, port, protocol, ...clientOptions } = opts;
|
|
25
24
|
const client = new Client({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
host: opts.host,
|
|
30
|
-
port: opts.port ?? 443,
|
|
31
|
-
protocol: opts.protocol ?? "https",
|
|
32
|
-
},
|
|
33
|
-
],
|
|
25
|
+
...clientOptions,
|
|
26
|
+
apiKey,
|
|
27
|
+
nodes: [{ host, port: port ?? 443, protocol: protocol ?? "https" }],
|
|
34
28
|
});
|
|
35
29
|
return async (query, options) => {
|
|
36
30
|
const response = await client
|
|
37
|
-
.collections<TypesenseRecord>(
|
|
31
|
+
.collections<TypesenseRecord>(collection)
|
|
38
32
|
.documents()
|
|
39
33
|
.search(
|
|
40
34
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { stableId } from "../content/tooltip-id.ts";
|
|
3
3
|
|
|
4
4
|
import type { MessageModel } from "./message.ts";
|
|
5
5
|
|
|
@@ -28,7 +28,7 @@ const modelJson = JSON.stringify(model).replaceAll("<", "\\u003c");
|
|
|
28
28
|
|
|
29
29
|
// Unique per rendered composer (a page can hold several), so the textarea's
|
|
30
30
|
// aria-describedby can point at ITS error container and no other.
|
|
31
|
-
const payloadErrorsId =
|
|
31
|
+
const payloadErrorsId = stableId(Astro.locals, "blume-payload-errors", [modelJson]);
|
|
32
32
|
|
|
33
33
|
const LABEL_ROW =
|
|
34
34
|
"mb-1 flex flex-wrap items-baseline gap-x-1.5 font-medium text-foreground text-xs";
|