From ff528a0db6325c6ff052fbf6d0565815cf688c54 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Jun 2026 20:55:54 +0000 Subject: [PATCH 01/11] feat(docs): redesign home page as an animated dark landing page Replace the plain docs home with a Linear/Vercel-style dark landing page: animated grid + glow background, aurora gradient headline, code card with a rotating border beam, framework marquee, scroll-reveal feature grid, an "observability without the tradeoff" section, roadmap, and a final CTA. - Animations via motion (framer-motion); CSS keyframes in global.css with a prefers-reduced-motion guard - Class merging via cnfast (fast clsx + tailwind-merge drop-in) - Messaging aligned with the README: drop-in for Express/Fastify/Hono/Elysia, two-line setup, OTLP export, REST-today roadmap --- apps/docs/app/(home)/_components/below.tsx | 258 +++++++++++++++++++++ apps/docs/app/(home)/_components/hero.tsx | 156 +++++++++++++ apps/docs/app/(home)/page.tsx | 52 +---- apps/docs/app/global.css | 97 +++++++- apps/docs/lib/utils.ts | 2 + apps/docs/package.json | 4 +- bun.lock | 16 +- 7 files changed, 532 insertions(+), 53 deletions(-) create mode 100644 apps/docs/app/(home)/_components/below.tsx create mode 100644 apps/docs/app/(home)/_components/hero.tsx create mode 100644 apps/docs/lib/utils.ts diff --git a/apps/docs/app/(home)/_components/below.tsx b/apps/docs/app/(home)/_components/below.tsx new file mode 100644 index 0000000..da579e7 --- /dev/null +++ b/apps/docs/app/(home)/_components/below.tsx @@ -0,0 +1,258 @@ +"use client"; + +import Link from "next/link"; +import { motion } from "motion/react"; +import { + Activity, + ScrollText, + FlaskConical, + ShieldCheck, + Share2, + Lock, + Boxes, + Cable, + KeyRound, + Check, + Circle, + ArrowRight, + type LucideIcon, +} from "lucide-react"; +import { cn } from "@/lib/utils"; + +const reveal = { + initial: { opacity: 0, y: 24 }, + whileInView: { opacity: 1, y: 0 }, + viewport: { once: true, margin: "-80px" }, + transition: { duration: 0.5, ease: "easeOut" }, +} as const; + +const FEATURES: { + icon: LucideIcon; + title: string; + body: string; + badge?: string; +}[] = [ + { + icon: Activity, + title: "Real-time tracing", + body: "A live waterfall of every request — spans, timings and parent/child relationships as they happen.", + }, + { + icon: ScrollText, + title: "Wide-event logs", + body: "Logs auto-linked to the active trace. Add context once and see it on every log in the request.", + }, + { + icon: FlaskConical, + title: "API playground", + body: "Fire requests at your own endpoints in a multi-tab client — no Postman, no context switch.", + }, + { + icon: ShieldCheck, + title: "Schema-aware", + body: "Request templates auto-generated from your Zod, Valibot or Standard Schema validators.", + }, + { + icon: Share2, + title: "OpenTelemetry export", + body: "Ship the same traces over OTLP/HTTP to Grafana, Honeycomb, Datadog or an OTel Collector.", + badge: "new", + }, + { + icon: Lock, + title: "Self-hosted & MIT", + body: "Runs in-process, alongside your app. Your data never leaves your machine. Zero lock-in.", + }, +]; + +const WITHOUT = [ + { + icon: Boxes, + title: "Without the rewrite", + body: "Encore.ts gives you a dashboard — if you rebuild your app on its framework. Vision is just middleware on the app you have.", + }, + { + icon: Cable, + title: "Without the wiring", + body: "Raw OpenTelemetry means an SDK, a collector and a backend before you see a single span. Vision works the moment you add it.", + }, + { + icon: KeyRound, + title: "Without the lock-in", + body: "Self-hosted and MIT-licensed. Develop locally, then export to whatever production backend you already run.", + }, +]; + +const ROADMAP: { label: string; done: boolean; badge?: string }[] = [ + { label: "REST", done: true }, + { label: "OpenTelemetry export", done: true, badge: "new" }, + { label: "GraphQL", done: false }, + { label: "tRPC", done: false }, + { label: "MCP", done: false }, +]; + +function Badge({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + +export function Below() { + return ( + <> + {/* Features */} +
+ +

+ Everything you need to see inside your API +

+

+ One dashboard for traces, logs and testing — wired into your + framework, not bolted on. +

+
+ +
+ {FEATURES.map((f, i) => ( + +
+ +
+

+ {f.title} + {f.badge && {f.badge}} +

+

+ {f.body} +

+
+ ))} +
+
+ + {/* Why / without */} +
+ +

+ Observability without the tradeoff +

+

+ The usual options ask you to give something up. Vision doesn't. +

+
+ +
+ {WITHOUT.map((w, i) => ( + + +

{w.title}

+

+ {w.body} +

+
+ ))} +
+ + + + See the full comparison with Encore.ts + + + +
+ + {/* Roadmap */} +
+ +

+ Roadmap +

+

+ REST and OpenTelemetry export ship today. Protocols are next. +

+
+ + + {ROADMAP.map((r) => ( +
  • + {r.done ? ( + + ) : ( + + )} + + {r.label} + + {r.badge && {r.badge}} +
  • + ))} +
    +
    + + {/* Final CTA */} +
    + +
    +

    + Ready to see what your API is doing? +

    +

    + Add Vision in two lines and open the dashboard. No signup, no agent, + no data leaving your machine. +

    +
    + + Get started + + + + View on GitHub + +
    + +
    + + ); +} diff --git a/apps/docs/app/(home)/_components/hero.tsx b/apps/docs/app/(home)/_components/hero.tsx new file mode 100644 index 0000000..7410f7f --- /dev/null +++ b/apps/docs/app/(home)/_components/hero.tsx @@ -0,0 +1,156 @@ +"use client"; + +import Link from "next/link"; +import { motion } from "motion/react"; +import { ArrowRight, Star, Terminal } from "lucide-react"; + +const FRAMEWORKS = ["Express", "Fastify", "Hono", "Elysia", "Next.js"]; + +export function Hero() { + return ( +
    + {/* Background: grid + glow blobs */} +
    +
    +
    +
    +
    +
    + +
    + {/* Left: copy */} + + + + + + + Open source · Self-hosted · MIT + + +

    + Drop-in{" "} + + observability + {" "} + for your TypeScript API +

    + +

    + Add live traces, logs, and an API playground to the Express, + Fastify, Hono or Elysia app you already have. Two lines of code — no + rewrite, no vendor lock-in. +

    + +
    + + Get started + + + + + Star on GitHub + +
    + +

    + {">"} Develop + locally, then ship the same traces to any{" "} + + OpenTelemetry + {" "} + backend. +

    +
    + + {/* Right: code card */} + +
    +
    + + + + + + server.ts + +
    +
    +              
    +                
    +                  {"// 1. add the adapter"}
    +                
    +                {"\n"}
    +                import
    +                
    +                  {" { visionAdapter } "}
    +                
    +                from
    +                
    +                  {" '@getvision/adapter-express'"}
    +                
    +                {"\n\n"}
    +                
    +                  {"// 2. mount it on the app you already have"}
    +                
    +                {"\n"}
    +                app.
    +                use
    +                (
    +                visionAdapter
    +                ({"{ "}
    +                port
    +                : 
    +                9500
    +                {" }))"}
    +                {"\n\n"}
    +                
    +                
    +                  {" dashboard live at "}
    +                
    +                localhost:9500
    +              
    +            
    +
    +
    +
    + + {/* Framework marquee */} +
    +

    + Works with the stack you already run +

    +
    +
    + {[...FRAMEWORKS, ...FRAMEWORKS, ...FRAMEWORKS].map((name, i) => ( + + {name} + + ))} +
    +
    +
    +
    + ); +} diff --git a/apps/docs/app/(home)/page.tsx b/apps/docs/app/(home)/page.tsx index a45f7ee..4d8c7dc 100644 --- a/apps/docs/app/(home)/page.tsx +++ b/apps/docs/app/(home)/page.tsx @@ -1,53 +1,11 @@ -import Link from 'next/link'; +import { Hero } from "./_components/hero"; +import { Below } from "./_components/below"; export default function HomePage() { return ( -
    -
    -

    Vision

    -

    - Universal observability for modern apps -

    -

    - One tool for REST, tRPC, GraphQL, MCP. Beautiful UI, < 5min setup, open source. -

    -
    - -
    - - Get Started - - - Quickstart - -
    - -
    -
    -

    🚀 Fast Setup

    -

    - One middleware, zero configuration. Up and running in under 5 minutes. -

    -
    -
    -

    🎨 Beautiful UI

    -

    - Modern dashboard with real-time tracing, API explorer, and dark mode. -

    -
    -
    -

    🌐 Universal Protocols

    -

    - REST, tRPC, GraphQL, MCP - all in one dashboard. No more tool switching. -

    -
    -
    +
    + +
    ); } diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index 50b3bc2..1fb03ef 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -1,3 +1,94 @@ -@import 'tailwindcss'; -@import 'fumadocs-ui/css/neutral.css'; -@import 'fumadocs-ui/css/preset.css'; +@import "tailwindcss"; +@import "fumadocs-ui/css/neutral.css"; +@import "fumadocs-ui/css/preset.css"; + +/* ---------- Landing page animations ---------- */ + +@keyframes aurora-shift { + 0%, + 100% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } +} + +@keyframes marquee { + to { + transform: translateX(-50%); + } +} + +@keyframes float-slow { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-18px); + } +} + +@keyframes beam-spin { + to { + transform: rotate(360deg); + } +} + +.animate-aurora { + background-size: 200% auto; + animation: aurora-shift 6s ease-in-out infinite; +} + +.animate-marquee { + animation: marquee 24s linear infinite; +} + +/* Fade a grid layer towards the edges */ +.grid-fade-mask { + -webkit-mask-image: radial-gradient( + ellipse 65% 55% at 50% 0%, + #000 55%, + transparent 100% + ); + mask-image: radial-gradient( + ellipse 65% 55% at 50% 0%, + #000 55%, + transparent 100% + ); +} + +/* Rotating conic "border beam" around a card */ +.beam-border { + position: relative; +} +.beam-border::before { + content: ""; + position: absolute; + inset: -1px; + border-radius: inherit; + padding: 1px; + background: conic-gradient( + from 0deg, + transparent 0 65%, + #a78bfa 80%, + #e879f9 90%, + transparent 100% + ); + -webkit-mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + animation: beam-spin 6s linear infinite; + pointer-events: none; +} + +@media (prefers-reduced-motion: reduce) { + .animate-aurora, + .animate-marquee, + .beam-border::before { + animation: none; + } +} diff --git a/apps/docs/lib/utils.ts b/apps/docs/lib/utils.ts new file mode 100644 index 0000000..ed9124c --- /dev/null +++ b/apps/docs/lib/utils.ts @@ -0,0 +1,2 @@ +// Fast drop-in `cn` (clsx + tailwind-merge) — https://github.com/aidenybai/cnfast +export { cn } from "cnfast"; diff --git a/apps/docs/package.json b/apps/docs/package.json index c03cf6c..5956dbc 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -13,7 +13,9 @@ "next": "15.5.4", "react": "catalog:", "react-dom": "catalog:", + "cnfast": "^0.0.8", "lucide-react": "^0.544.0", + "motion": "^11.18.1", "fumadocs-ui": "15.8.5", "fumadocs-core": "15.8.5", "fumadocs-mdx": "12.0.3" @@ -28,4 +30,4 @@ "tailwindcss": "^4.1.14", "postcss": "^8.5.6" } -} \ No newline at end of file +} diff --git a/bun.lock b/bun.lock index 78b9f83..d5a1d39 100644 --- a/bun.lock +++ b/bun.lock @@ -18,10 +18,12 @@ "name": "docs", "version": "0.0.1", "dependencies": { + "cnfast": "^0.0.8", "fumadocs-core": "15.8.5", "fumadocs-mdx": "12.0.3", "fumadocs-ui": "15.8.5", "lucide-react": "^0.544.0", + "motion": "^11.18.1", "next": "15.5.4", "react": "catalog:", "react-dom": "catalog:", @@ -241,7 +243,7 @@ }, "packages/core": { "name": "@getvision/core", - "version": "0.2.1", + "version": "0.3.0-a99fcdb-develop", "dependencies": { "mime-types": "^2.1.35", "nanoid": "^5.0.7", @@ -278,7 +280,7 @@ }, "packages/server": { "name": "@getvision/server", - "version": "1.0.2", + "version": "1.1.0-a99fcdb-develop", "dependencies": { "@getvision/core": "workspace:*", "bullmq": "^5.62.0", @@ -1110,6 +1112,8 @@ "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="], + "cnfast": ["cnfast@0.0.8", "", { "bin": { "cnfast": "bin/cli.js" } }, "sha512-EjXKMfGfdwtV4AcNSQ6AwQaVzpC1B7IxeiwA3FlhTXz+YFlMKVi4c1JX9tgD2QOlahQXjB8KUXrBaYG+3v871Q=="], + "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], "color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], @@ -1382,6 +1386,8 @@ "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="], + "framer-motion": ["framer-motion@11.18.2", "", { "dependencies": { "motion-dom": "^11.18.1", "motion-utils": "^11.18.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w=="], + "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="], @@ -1842,6 +1848,12 @@ "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], + "motion": ["motion@11.18.2", "", { "dependencies": { "framer-motion": "^11.18.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-JLjvFDuFr42NFtcVoMAyC2sEjnpA8xpy6qWPyzQvCloznAyQ8FIXioxWfHiLtgYhoVpfUqSWpn1h9++skj9+Wg=="], + + "motion-dom": ["motion-dom@11.18.1", "", { "dependencies": { "motion-utils": "^11.18.1" } }, "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw=="], + + "motion-utils": ["motion-utils@11.18.1", "", {}, "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA=="], + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "msgpackr": ["msgpackr@1.11.5", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA=="], From 05d27c4d6caf1f25a0010e6451947bdf4c353415 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Jun 2026 21:04:40 +0000 Subject: [PATCH 02/11] fix(docs): replace framework marquee with a static row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five frameworks don't need a scrolling marquee — the looping duplicates read as filler. Show Express/Fastify/Hono/Elysia/Next.js once, centered. Drops the now-unused marquee keyframes/utility. --- apps/docs/app/(home)/_components/hero.tsx | 24 +++++++++++------------ apps/docs/app/global.css | 11 ----------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/apps/docs/app/(home)/_components/hero.tsx b/apps/docs/app/(home)/_components/hero.tsx index 7410f7f..519eb07 100644 --- a/apps/docs/app/(home)/_components/hero.tsx +++ b/apps/docs/app/(home)/_components/hero.tsx @@ -133,22 +133,20 @@ export function Hero() { - {/* Framework marquee */} -
    + {/* Supported frameworks */} +

    Works with the stack you already run

    -
    -
    - {[...FRAMEWORKS, ...FRAMEWORKS, ...FRAMEWORKS].map((name, i) => ( - - {name} - - ))} -
    +
    + {FRAMEWORKS.map((name) => ( + + {name} + + ))}
    diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index 1fb03ef..9a43d9d 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -14,12 +14,6 @@ } } -@keyframes marquee { - to { - transform: translateX(-50%); - } -} - @keyframes float-slow { 0%, 100% { @@ -41,10 +35,6 @@ animation: aurora-shift 6s ease-in-out infinite; } -.animate-marquee { - animation: marquee 24s linear infinite; -} - /* Fade a grid layer towards the edges */ .grid-fade-mask { -webkit-mask-image: radial-gradient( @@ -87,7 +77,6 @@ @media (prefers-reduced-motion: reduce) { .animate-aurora, - .animate-marquee, .beam-border::before { animation: none; } From 019a685a75d94e809ed2b8fca0c7efd6d81db38f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Jun 2026 21:21:38 +0000 Subject: [PATCH 03/11] refactor(docs): drop Roadmap section from landing page The roadmap already lives in the README and docs; on the landing it read as "what's missing" and undercut the pitch. Removes the section and its now-unused imports/data. --- apps/docs/app/(home)/_components/below.tsx | 55 ---------------------- 1 file changed, 55 deletions(-) diff --git a/apps/docs/app/(home)/_components/below.tsx b/apps/docs/app/(home)/_components/below.tsx index da579e7..d04e599 100644 --- a/apps/docs/app/(home)/_components/below.tsx +++ b/apps/docs/app/(home)/_components/below.tsx @@ -12,12 +12,9 @@ import { Boxes, Cable, KeyRound, - Check, - Circle, ArrowRight, type LucideIcon, } from "lucide-react"; -import { cn } from "@/lib/utils"; const reveal = { initial: { opacity: 0, y: 24 }, @@ -83,14 +80,6 @@ const WITHOUT = [ }, ]; -const ROADMAP: { label: string; done: boolean; badge?: string }[] = [ - { label: "REST", done: true }, - { label: "OpenTelemetry export", done: true, badge: "new" }, - { label: "GraphQL", done: false }, - { label: "tRPC", done: false }, - { label: "MCP", done: false }, -]; - function Badge({ children }: { children: React.ReactNode }) { return ( @@ -176,50 +165,6 @@ export function Below() { - {/* Roadmap */} -
    - -

    - Roadmap -

    -

    - REST and OpenTelemetry export ship today. Protocols are next. -

    -
    - - - {ROADMAP.map((r) => ( -
  • - {r.done ? ( - - ) : ( - - )} - - {r.label} - - {r.badge && {r.badge}} -
  • - ))} -
    -
    - {/* Final CTA */}
    Date: Tue, 30 Jun 2026 21:44:23 +0000 Subject: [PATCH 04/11] feat(docs): mint palette, WebGL Beams hero, dashboard showcase, dark-only - Recolor the landing from violet to an emerald/teal/mint palette - Add an animated WebGL Beams hero background (React Bits / three.js), lazy- loaded client-side and disabled under prefers-reduced-motion - Add a "Two lines in. Full visibility out." showcase: the 2-line setup next to a dashboard preview (trace waterfall + logs) so the landing shows what you get - Force dark theme site-wide and hide the theme toggle (no light mode/fallbacks) --- apps/docs/app/(home)/_components/beams-bg.tsx | 42 +++ .../app/(home)/_components/beams/Beams.css | 5 + .../app/(home)/_components/beams/Beams.tsx | 352 ++++++++++++++++++ apps/docs/app/(home)/_components/below.tsx | 14 +- apps/docs/app/(home)/_components/hero.tsx | 180 +++------ apps/docs/app/(home)/_components/showcase.tsx | 171 +++++++++ apps/docs/app/(home)/page.tsx | 2 + apps/docs/app/global.css | 4 +- apps/docs/app/layout.tsx | 26 +- apps/docs/lib/layout.shared.tsx | 4 + apps/docs/package.json | 15 +- bun.lock | 105 +++++- 12 files changed, 775 insertions(+), 145 deletions(-) create mode 100644 apps/docs/app/(home)/_components/beams-bg.tsx create mode 100644 apps/docs/app/(home)/_components/beams/Beams.css create mode 100644 apps/docs/app/(home)/_components/beams/Beams.tsx create mode 100644 apps/docs/app/(home)/_components/showcase.tsx diff --git a/apps/docs/app/(home)/_components/beams-bg.tsx b/apps/docs/app/(home)/_components/beams-bg.tsx new file mode 100644 index 0000000..c5e261a --- /dev/null +++ b/apps/docs/app/(home)/_components/beams-bg.tsx @@ -0,0 +1,42 @@ +"use client"; + +import dynamic from "next/dynamic"; +import { useEffect, useState } from "react"; + +// Heavy WebGL (three.js) — load it lazily and only on the client. +const Beams = dynamic(() => import("./beams/Beams"), { ssr: false }); + +/** + * Renders the animated Beams background, unless the user has asked to reduce + * motion — in which case the hero's static background shows through instead. + */ +export function BeamsBg() { + const [show, setShow] = useState(false); + + useEffect(() => { + const motionOk = window.matchMedia("(prefers-reduced-motion: reduce)"); + const update = () => setShow(!motionOk.matches); + update(); + motionOk.addEventListener("change", update); + return () => motionOk.removeEventListener("change", update); + }, []); + + if (!show) return null; + + return ( +
    + + {/* fade the beams into the page background at the bottom */} +
    +
    + ); +} diff --git a/apps/docs/app/(home)/_components/beams/Beams.css b/apps/docs/app/(home)/_components/beams/Beams.css new file mode 100644 index 0000000..6c5dac2 --- /dev/null +++ b/apps/docs/app/(home)/_components/beams/Beams.css @@ -0,0 +1,5 @@ +.beams-container { + position: relative; + width: 100%; + height: 100%; +} diff --git a/apps/docs/app/(home)/_components/beams/Beams.tsx b/apps/docs/app/(home)/_components/beams/Beams.tsx new file mode 100644 index 0000000..fa2cf61 --- /dev/null +++ b/apps/docs/app/(home)/_components/beams/Beams.tsx @@ -0,0 +1,352 @@ +// @ts-nocheck +/* eslint-disable react/no-unknown-property */ +// Beams background — adapted from React Bits (https://reactbits.dev), MIT. +'use client'; + +import { + forwardRef, + useImperativeHandle, + useEffect, + useRef, + useMemo, +} from 'react'; + +import * as THREE from 'three'; + +import { Canvas, useFrame } from '@react-three/fiber'; +import { PerspectiveCamera } from '@react-three/drei'; +import { degToRad } from 'three/src/math/MathUtils.js'; + +import './Beams.css'; + +function extendMaterial(BaseMaterial, cfg) { + const physical = THREE.ShaderLib.physical; + const { + vertexShader: baseVert, + fragmentShader: baseFrag, + uniforms: baseUniforms, + } = physical; + const baseDefines = physical.defines ?? {}; + + const uniforms = THREE.UniformsUtils.clone(baseUniforms); + + const defaults = new BaseMaterial(cfg.material || {}); + + if (defaults.color) uniforms.diffuse.value = defaults.color; + if ('roughness' in defaults) uniforms.roughness.value = defaults.roughness; + if ('metalness' in defaults) uniforms.metalness.value = defaults.metalness; + if ('envMap' in defaults) uniforms.envMap.value = defaults.envMap; + if ('envMapIntensity' in defaults) + uniforms.envMapIntensity.value = defaults.envMapIntensity; + + Object.entries(cfg.uniforms ?? {}).forEach(([key, u]) => { + uniforms[key] = + u !== null && typeof u === 'object' && 'value' in u ? u : { value: u }; + }); + + let vert = `${cfg.header}\n${cfg.vertexHeader ?? ''}\n${baseVert}`; + let frag = `${cfg.header}\n${cfg.fragmentHeader ?? ''}\n${baseFrag}`; + + for (const [inc, code] of Object.entries(cfg.vertex ?? {})) { + vert = vert.replace(inc, `${inc}\n${code}`); + } + for (const [inc, code] of Object.entries(cfg.fragment ?? {})) { + frag = frag.replace(inc, `${inc}\n${code}`); + } + + const mat = new THREE.ShaderMaterial({ + defines: { ...baseDefines }, + uniforms, + vertexShader: vert, + fragmentShader: frag, + lights: true, + fog: !!cfg.material?.fog, + }); + + return mat; +} + +const CanvasWrapper = ({ children }) => ( + + {children} + +); + +const hexToNormalizedRGB = (hex) => { + const clean = hex.replace('#', ''); + const r = parseInt(clean.substring(0, 2), 16); + const g = parseInt(clean.substring(2, 4), 16); + const b = parseInt(clean.substring(4, 6), 16); + return [r / 255, g / 255, b / 255]; +}; + +const noise = ` +float random (in vec2 st) { + return fract(sin(dot(st.xy, + vec2(12.9898,78.233)))* + 43758.5453123); +} +float noise (in vec2 st) { + vec2 i = floor(st); + vec2 f = fract(st); + float a = random(i); + float b = random(i + vec2(1.0, 0.0)); + float c = random(i + vec2(0.0, 1.0)); + float d = random(i + vec2(1.0, 1.0)); + vec2 u = f * f * (3.0 - 2.0 * f); + return mix(a, b, u.x) + + (c - a)* u.y * (1.0 - u.x) + + (d - b) * u.x * u.y; +} +vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} +vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} +vec3 fade(vec3 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);} +float cnoise(vec3 P){ + vec3 Pi0 = floor(P); + vec3 Pi1 = Pi0 + vec3(1.0); + Pi0 = mod(Pi0, 289.0); + Pi1 = mod(Pi1, 289.0); + vec3 Pf0 = fract(P); + vec3 Pf1 = Pf0 - vec3(1.0); + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec4 iy = vec4(Pi0.yy, Pi1.yy); + vec4 iz0 = Pi0.zzzz; + vec4 iz1 = Pi1.zzzz; + vec4 ixy = permute(permute(ix) + iy); + vec4 ixy0 = permute(ixy + iz0); + vec4 ixy1 = permute(ixy + iz1); + vec4 gx0 = ixy0 / 7.0; + vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5; + gx0 = fract(gx0); + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); + vec4 sz0 = step(gz0, vec4(0.0)); + gx0 -= sz0 * (step(0.0, gx0) - 0.5); + gy0 -= sz0 * (step(0.0, gy0) - 0.5); + vec4 gx1 = ixy1 / 7.0; + vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5; + gx1 = fract(gx1); + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); + vec4 sz1 = step(gz1, vec4(0.0)); + gx1 -= sz1 * (step(0.0, gx1) - 0.5); + gy1 -= sz1 * (step(0.0, gy1) - 0.5); + vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); + vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); + vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); + vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); + vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); + vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); + vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); + vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); + vec4 norm0 = taylorInvSqrt(vec4(dot(g000,g000),dot(g010,g010),dot(g100,g100),dot(g110,g110))); + g000 *= norm0.x; g010 *= norm0.y; g100 *= norm0.z; g110 *= norm0.w; + vec4 norm1 = taylorInvSqrt(vec4(dot(g001,g001),dot(g011,g011),dot(g101,g101),dot(g111,g111))); + g001 *= norm1.x; g011 *= norm1.y; g101 *= norm1.z; g111 *= norm1.w; + float n000 = dot(g000, Pf0); + float n100 = dot(g100, vec3(Pf1.x,Pf0.yz)); + float n010 = dot(g010, vec3(Pf0.x,Pf1.y,Pf0.z)); + float n110 = dot(g110, vec3(Pf1.xy,Pf0.z)); + float n001 = dot(g001, vec3(Pf0.xy,Pf1.z)); + float n101 = dot(g101, vec3(Pf1.x,Pf0.y,Pf1.z)); + float n011 = dot(g011, vec3(Pf0.x,Pf1.yz)); + float n111 = dot(g111, Pf1); + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix(vec4(n000,n100,n010,n110),vec4(n001,n101,n011,n111),fade_xyz.z); + vec2 n_yz = mix(n_z.xy,n_z.zw,fade_xyz.y); + float n_xyz = mix(n_yz.x,n_yz.y,fade_xyz.x); + return 2.2 * n_xyz; +} +`; + +const Beams = ({ + beamWidth = 2, + beamHeight = 15, + beamNumber = 12, + lightColor = '#ffffff', + speed = 2, + noiseIntensity = 1.75, + scale = 0.2, + rotation = 0, +}) => { + const meshRef = useRef(null); + const beamMaterial = useMemo( + () => + extendMaterial(THREE.MeshStandardMaterial, { + header: ` + varying vec3 vEye; + varying float vNoise; + varying vec2 vUv; + varying vec3 vPosition; + uniform float time; + uniform float uSpeed; + uniform float uNoiseIntensity; + uniform float uScale; + ${noise}`, + vertexHeader: ` + float getPos(vec3 pos) { + vec3 noisePos = + vec3(pos.x * 0., pos.y - uv.y, pos.z + time * uSpeed * 3.) * uScale; + return cnoise(noisePos); + } + vec3 getCurrentPos(vec3 pos) { + vec3 newpos = pos; + newpos.z += getPos(pos); + return newpos; + } + vec3 getNormal(vec3 pos) { + vec3 curpos = getCurrentPos(pos); + vec3 nextposX = getCurrentPos(pos + vec3(0.01, 0.0, 0.0)); + vec3 nextposZ = getCurrentPos(pos + vec3(0.0, -0.01, 0.0)); + vec3 tangentX = normalize(nextposX - curpos); + vec3 tangentZ = normalize(nextposZ - curpos); + return normalize(cross(tangentZ, tangentX)); + }`, + fragmentHeader: '', + vertex: { + '#include ': `transformed.z += getPos(transformed.xyz);`, + '#include ': `objectNormal = getNormal(position.xyz);`, + }, + fragment: { + '#include ': ` + float randomNoise = noise(gl_FragCoord.xy); + gl_FragColor.rgb -= randomNoise / 15. * uNoiseIntensity;`, + }, + material: { fog: true }, + uniforms: { + diffuse: new THREE.Color(...hexToNormalizedRGB('#000000')), + time: { shared: true, mixed: true, linked: true, value: 0 }, + roughness: 0.3, + metalness: 0.3, + uSpeed: { shared: true, mixed: true, linked: true, value: speed }, + envMapIntensity: 10, + uNoiseIntensity: noiseIntensity, + uScale: scale, + }, + }), + [speed, noiseIntensity, scale] + ); + + return ( + + + + + + + + + + ); +}; + +function createStackedPlanesBufferGeometry( + n, + width, + height, + spacing, + heightSegments +) { + const geometry = new THREE.BufferGeometry(); + const numVertices = n * (heightSegments + 1) * 2; + const numFaces = n * heightSegments * 2; + const positions = new Float32Array(numVertices * 3); + const indices = new Uint32Array(numFaces * 3); + const uvs = new Float32Array(numVertices * 2); + + let vertexOffset = 0; + let indexOffset = 0; + let uvOffset = 0; + const totalWidth = n * width + (n - 1) * spacing; + const xOffsetBase = -totalWidth / 2; + + for (let i = 0; i < n; i++) { + const xOffset = xOffsetBase + i * (width + spacing); + const uvXOffset = Math.random() * 300; + const uvYOffset = Math.random() * 300; + + for (let j = 0; j <= heightSegments; j++) { + const y = height * (j / heightSegments - 0.5); + const v0 = [xOffset, y, 0]; + const v1 = [xOffset + width, y, 0]; + positions.set([...v0, ...v1], vertexOffset * 3); + + const uvY = j / heightSegments; + uvs.set( + [uvXOffset, uvY + uvYOffset, uvXOffset + 1, uvY + uvYOffset], + uvOffset + ); + + if (j < heightSegments) { + const a = vertexOffset, + b = vertexOffset + 1, + c = vertexOffset + 2, + d = vertexOffset + 3; + indices.set([a, b, c, c, b, d], indexOffset); + indexOffset += 6; + } + vertexOffset += 2; + uvOffset += 4; + } + } + + geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); + geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2)); + geometry.setIndex(new THREE.BufferAttribute(indices, 1)); + geometry.computeVertexNormals(); + return geometry; +} + +const MergedPlanes = forwardRef(({ material, width, count, height }, ref) => { + const mesh = useRef(null); + useImperativeHandle(ref, () => mesh.current); + const geometry = useMemo( + () => createStackedPlanesBufferGeometry(count, width, height, 0, 100), + [count, width, height] + ); + useFrame((_, delta) => { + mesh.current.material.uniforms.time.value += 0.1 * delta; + }); + return ; +}); +MergedPlanes.displayName = 'MergedPlanes'; + +const PlaneNoise = forwardRef((props, ref) => ( + +)); +PlaneNoise.displayName = 'PlaneNoise'; + +const DirLight = ({ position, color }) => { + const dir = useRef(null); + useEffect(() => { + if (!dir.current) return; + const cam = dir.current.shadow.camera; + if (!cam) return; + cam.top = 24; + cam.bottom = -24; + cam.left = -24; + cam.right = 24; + cam.far = 64; + dir.current.shadow.bias = -0.004; + }, []); + return ( + + ); +}; + +export default Beams; diff --git a/apps/docs/app/(home)/_components/below.tsx b/apps/docs/app/(home)/_components/below.tsx index d04e599..f27dd08 100644 --- a/apps/docs/app/(home)/_components/below.tsx +++ b/apps/docs/app/(home)/_components/below.tsx @@ -82,7 +82,7 @@ const WITHOUT = [ function Badge({ children }: { children: React.ReactNode }) { return ( - + {children} ); @@ -109,9 +109,9 @@ export function Below() { key={f.title} {...reveal} transition={{ ...reveal.transition, delay: i * 0.05 }} - className="group relative rounded-xl border border-fd-border bg-fd-card/50 p-6 transition hover:border-violet-500/40 hover:bg-fd-card" + className="group relative rounded-xl border border-fd-border bg-fd-card/50 p-6 transition hover:border-emerald-500/40 hover:bg-fd-card" > -
    +

    @@ -145,7 +145,7 @@ export function Below() { transition={{ ...reveal.transition, delay: i * 0.07 }} className="rounded-xl border border-fd-border bg-fd-card/50 p-6" > - +

    {w.title}

    {w.body} @@ -157,7 +157,7 @@ export function Below() { See the full comparison with Encore.ts @@ -171,7 +171,7 @@ export function Below() { {...reveal} className="relative mx-auto max-w-4xl overflow-hidden rounded-2xl border border-fd-border bg-fd-card/50 px-6 py-16 text-center" > -

    +

    Ready to see what your API is doing?

    @@ -182,7 +182,7 @@ export function Below() {
    Get started diff --git a/apps/docs/app/(home)/_components/hero.tsx b/apps/docs/app/(home)/_components/hero.tsx index 519eb07..f5be1bd 100644 --- a/apps/docs/app/(home)/_components/hero.tsx +++ b/apps/docs/app/(home)/_components/hero.tsx @@ -2,136 +2,78 @@ import Link from "next/link"; import { motion } from "motion/react"; -import { ArrowRight, Star, Terminal } from "lucide-react"; +import { ArrowRight, Star } from "lucide-react"; +import { BeamsBg } from "./beams-bg"; const FRAMEWORKS = ["Express", "Fastify", "Hono", "Elysia", "Next.js"]; export function Hero() { return ( -
    - {/* Background: grid + glow blobs */} -
    -
    -
    -
    -
    +
    + {/* Animated WebGL beams */} + + + {/* Static background (shown when beams are off, e.g. reduced motion) */} +
    +
    +
    +
    -
    - {/* Left: copy */} - - - - - - - Open source · Self-hosted · MIT + + + + + + Open source · Self-hosted · MIT + -

    - Drop-in{" "} - - observability - {" "} - for your TypeScript API -

    - -

    - Add live traces, logs, and an API playground to the Express, - Fastify, Hono or Elysia app you already have. Two lines of code — no - rewrite, no vendor lock-in. -

    +

    + Drop-in{" "} + + observability + {" "} + for your TypeScript API +

    -
    - - Get started - - - - - Star on GitHub - -
    +

    + Add live traces, logs, and an API playground to the Express, Fastify, + Hono or Elysia app you already have. Two lines of code — no rewrite, + no vendor lock-in. +

    -

    - {">"} Develop - locally, then ship the same traces to any{" "} - - OpenTelemetry - {" "} - backend. -

    -
    +
    + + Get started + + + + + Star on GitHub + +
    - {/* Right: code card */} - -
    -
    - - - - - - server.ts - -
    -
    -              
    -                
    -                  {"// 1. add the adapter"}
    -                
    -                {"\n"}
    -                import
    -                
    -                  {" { visionAdapter } "}
    -                
    -                from
    -                
    -                  {" '@getvision/adapter-express'"}
    -                
    -                {"\n\n"}
    -                
    -                  {"// 2. mount it on the app you already have"}
    -                
    -                {"\n"}
    -                app.
    -                use
    -                (
    -                visionAdapter
    -                ({"{ "}
    -                port
    -                : 
    -                9500
    -                {" }))"}
    -                {"\n\n"}
    -                
    -                
    -                  {" dashboard live at "}
    -                
    -                localhost:9500
    -              
    -            
    -
    -
    -
    +

    + {">"} Develop + locally, then ship the same traces to any{" "} + OpenTelemetry{" "} + backend. +

    + {/* Supported frameworks */}
    @@ -142,7 +84,7 @@ export function Hero() { {FRAMEWORKS.map((name) => ( {name} diff --git a/apps/docs/app/(home)/_components/showcase.tsx b/apps/docs/app/(home)/_components/showcase.tsx new file mode 100644 index 0000000..460fcde --- /dev/null +++ b/apps/docs/app/(home)/_components/showcase.tsx @@ -0,0 +1,171 @@ +"use client"; + +import { motion } from "motion/react"; +import { Terminal } from "lucide-react"; + +const reveal = { + initial: { opacity: 0, y: 24 }, + whileInView: { opacity: 1, y: 0 }, + viewport: { once: true, margin: "-80px" }, + transition: { duration: 0.5, ease: "easeOut" }, +} as const; + +// A stylised trace waterfall — offsets/widths are % of the request duration. +const SPANS = [ + { label: "GET /users", ms: "142ms", left: 0, width: 100, depth: 0 }, + { + label: "db.query · select users", + ms: "38ms", + left: 8, + width: 27, + depth: 1, + }, + { label: "cache.get", ms: "4ms", left: 36, width: 4, depth: 1 }, + { label: "serialize", ms: "6ms", left: 88, width: 8, depth: 1 }, +]; + +export function Showcase() { + return ( +
    + +

    + Two lines in. Full visibility out. +

    +

    + Mount the adapter, then open the dashboard — every request becomes a + trace you can read, replay and debug. +

    +
    + +
    + {/* Code card */} + +
    +
    + + + + + + server.ts + +
    +
    +              
    +                
    +                  {"// 1. add the adapter"}
    +                
    +                {"\n"}
    +                import
    +                
    +                  {" { visionAdapter } "}
    +                
    +                from
    +                
    +                  {" '@getvision/adapter-express'"}
    +                
    +                {"\n\n"}
    +                
    +                  {"// 2. mount it on the app you already have"}
    +                
    +                {"\n"}
    +                app.
    +                use
    +                (
    +                visionAdapter
    +                ({"{ "}
    +                port
    +                : 
    +                9500
    +                {" }))"}
    +                {"\n\n"}
    +                
    +                
    +                  {" dashboard live at "}
    +                
    +                localhost:9500
    +              
    +            
    +
    +
    + + {/* Dashboard mock */} + + {/* window bar */} +
    + + + + + Vision · localhost:9500 + +
    + + {/* tabs */} +
    + + Traces + + Logs + + Playground + +
    + + {/* request header row */} +
    +
    + + GET + + /users +
    +
    + + 200 + + 142 ms +
    +
    + + {/* waterfall */} +
    + {SPANS.map((s) => ( +
    + + {s.label} + +
    +
    +
    + + {s.ms} + +
    + ))} +
    + + {/* log line */} +
    + {" "} + + user.id=123 plan= + pro · request + completed + +
    + +
    +
    + ); +} diff --git a/apps/docs/app/(home)/page.tsx b/apps/docs/app/(home)/page.tsx index 4d8c7dc..7e4c509 100644 --- a/apps/docs/app/(home)/page.tsx +++ b/apps/docs/app/(home)/page.tsx @@ -1,10 +1,12 @@ import { Hero } from "./_components/hero"; +import { Showcase } from "./_components/showcase"; import { Below } from "./_components/below"; export default function HomePage() { return (
    +
    ); diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index 9a43d9d..86344d9 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -62,8 +62,8 @@ background: conic-gradient( from 0deg, transparent 0 65%, - #a78bfa 80%, - #e879f9 90%, + #34d399 80%, + #22d3ee 90%, transparent 100% ); -webkit-mask: diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx index d0f3844..6159fad 100644 --- a/apps/docs/app/layout.tsx +++ b/apps/docs/app/layout.tsx @@ -1,30 +1,36 @@ -import '@/app/global.css'; -import type { Metadata } from 'next'; -import { RootProvider } from 'fumadocs-ui/provider/next'; -import { Inter } from 'next/font/google'; +import "@/app/global.css"; +import type { Metadata } from "next"; +import { RootProvider } from "fumadocs-ui/provider/next"; +import { Inter } from "next/font/google"; const inter = Inter({ - subsets: ['latin'], + subsets: ["latin"], }); export const metadata: Metadata = { metadataBase: new URL( - process.env.NEXT_PUBLIC_SITE_URL ?? 'https://getvision.dev' + process.env.NEXT_PUBLIC_SITE_URL ?? "https://getvision.dev", ), robots: { index: true, follow: true, }, verification: { - google: 'gRXIMDfMK13pfDWOy8lxvHMB6RhduDzBp9guQwAhU7A', + google: "gRXIMDfMK13pfDWOy8lxvHMB6RhduDzBp9guQwAhU7A", }, }; -export default function Layout({ children }: LayoutProps<'/'>) { +export default function Layout({ children }: LayoutProps<"/">) { return ( - + - {children} + {/* Dark theme only — no light mode, no toggle */} + {children} ); diff --git a/apps/docs/lib/layout.shared.tsx b/apps/docs/lib/layout.shared.tsx index 5f0226d..e2ebb22 100644 --- a/apps/docs/lib/layout.shared.tsx +++ b/apps/docs/lib/layout.shared.tsx @@ -12,6 +12,10 @@ export function baseOptions(): BaseLayoutProps { nav: { title: 'Vision', }, + // Dark theme only — hide the light/dark toggle + themeSwitch: { + enabled: false, + }, links: [ { text: 'Documentation', diff --git a/apps/docs/package.json b/apps/docs/package.json index 5956dbc..5c1af2d 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -10,15 +10,18 @@ "postinstall": "fumadocs-mdx" }, "dependencies": { - "next": "15.5.4", - "react": "catalog:", - "react-dom": "catalog:", + "@react-three/drei": "^10.7.7", + "@react-three/fiber": "^9.6.1", "cnfast": "^0.0.8", + "fumadocs-core": "15.8.5", + "fumadocs-mdx": "12.0.3", + "fumadocs-ui": "15.8.5", "lucide-react": "^0.544.0", "motion": "^11.18.1", - "fumadocs-ui": "15.8.5", - "fumadocs-core": "15.8.5", - "fumadocs-mdx": "12.0.3" + "next": "15.5.4", + "react": "catalog:", + "react-dom": "catalog:", + "three": "^0.185.0" }, "devDependencies": { "@types/node": "24.6.2", diff --git a/bun.lock b/bun.lock index d5a1d39..84b8985 100644 --- a/bun.lock +++ b/bun.lock @@ -18,6 +18,8 @@ "name": "docs", "version": "0.0.1", "dependencies": { + "@react-three/drei": "^10.7.7", + "@react-three/fiber": "^9.6.1", "cnfast": "^0.0.8", "fumadocs-core": "15.8.5", "fumadocs-mdx": "12.0.3", @@ -27,6 +29,7 @@ "next": "15.5.4", "react": "catalog:", "react-dom": "catalog:", + "three": "^0.185.0", }, "devDependencies": { "@tailwindcss/postcss": "^4.1.14", @@ -442,6 +445,8 @@ "@commitlint/types": ["@commitlint/types@19.8.1", "", { "dependencies": { "@types/conventional-commits-parser": "^5.0.0", "chalk": "^5.3.0" } }, "sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw=="], + "@dimforge/rapier3d-compat": ["@dimforge/rapier3d-compat@0.12.0", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="], + "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="], "@elysia/eden": ["@elysia/eden@1.4.10", "", { "peerDependencies": { "elysia": ">=1.4.19" } }, "sha512-vcZXQcW6wZj6rhTxaiTkuCbVuS/yAJQ9jqCM6b83a5hu99F5Aj3HOyWXL17iod2Rz+pJpYsQGX0XaeoCsMpw2g=="], @@ -624,6 +629,10 @@ "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="], + "@mediapipe/tasks-vision": ["@mediapipe/tasks-vision@0.10.17", "", {}, "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg=="], + + "@monogrid/gainmap-js": ["@monogrid/gainmap-js@3.4.0", "", { "dependencies": { "promise-worker-transferable": "^1.0.4" }, "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg=="], + "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw=="], "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw=="], @@ -746,6 +755,10 @@ "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], + "@react-three/drei": ["@react-three/drei@10.7.7", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mediapipe/tasks-vision": "0.10.17", "@monogrid/gainmap-js": "^3.0.6", "@use-gesture/react": "^10.3.1", "camera-controls": "^3.1.0", "cross-env": "^7.0.3", "detect-gpu": "^5.0.56", "glsl-noise": "^0.0.0", "hls.js": "^1.5.17", "maath": "^0.10.8", "meshline": "^3.3.1", "stats-gl": "^2.2.8", "stats.js": "^0.17.0", "suspend-react": "^0.1.3", "three-mesh-bvh": "^0.8.3", "three-stdlib": "^2.35.6", "troika-three-text": "^0.52.4", "tunnel-rat": "^0.1.2", "use-sync-external-store": "^1.4.0", "utility-types": "^3.11.0", "zustand": "^5.0.1" }, "peerDependencies": { "@react-three/fiber": "^9.0.0", "react": "^19", "react-dom": "^19", "three": ">=0.159" }, "optionalPeers": ["react-dom"] }, "sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ=="], + + "@react-three/fiber": ["@react-three/fiber@9.6.1", "", { "dependencies": { "@babel/runtime": "^7.17.8", "@types/webxr": "*", "base64-js": "^1.5.1", "buffer": "^6.0.3", "its-fine": "^2.0.0", "react-use-measure": "^2.1.7", "scheduler": "^0.27.0", "suspend-react": "^0.1.3", "use-sync-external-store": "^1.4.0", "zustand": "^5.0.3" }, "peerDependencies": { "expo": ">=43.0", "expo-asset": ">=8.4", "expo-file-system": ">=11.0", "expo-gl": ">=11.0", "react": ">=19 <19.3", "react-dom": ">=19 <19.3", "react-native": ">=0.78", "three": ">=0.156" }, "optionalPeers": ["expo", "expo-asset", "expo-file-system", "expo-gl", "react-dom", "react-native"] }, "sha512-zF0rsKcVYpcJwbFEnv2HkHX9cvOEgsfQo/X8lwmR2dn13S4qEQJXir9fxf5js2LQFoXqxOY7MDkOkYx2uZ4gSg=="], + "@repo/eslint-config": ["@repo/eslint-config@workspace:packages/eslint-config"], "@repo/typescript-config": ["@repo/typescript-config@workspace:packages/typescript-config"], @@ -890,6 +903,8 @@ "@turbo/windows-arm64": ["@turbo/windows-arm64@2.9.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-1XUUyWW0W6FTSqGEhU8RHVqb2wP1SPkr7hIvBlMEwH9jr+sJQK5kqeosLJ/QaUv4ecSAd1ZhIrLoW7qslAzT4A=="], + "@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="], + "@types/better-sqlite3": ["@types/better-sqlite3@7.6.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA=="], "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="], @@ -902,6 +917,8 @@ "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], + "@types/draco3d": ["@types/draco3d@1.4.10", "", {}, "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw=="], + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], @@ -930,6 +947,8 @@ "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], + "@types/offscreencanvas": ["@types/offscreencanvas@2019.7.3", "", {}, "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A=="], + "@types/prismjs": ["@types/prismjs@1.26.6", "", {}, "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw=="], "@types/qs": ["@types/qs@6.15.0", "", {}, "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow=="], @@ -940,14 +959,22 @@ "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], + "@types/react-reconciler": ["@types/react-reconciler@0.28.9", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="], + "@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="], "@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="], "@types/serve-static": ["@types/serve-static@2.2.0", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*" } }, "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ=="], + "@types/stats.js": ["@types/stats.js@0.17.4", "", {}, "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="], + + "@types/three": ["@types/three@0.185.0", "", { "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": ">=0.5.17", "fflate": "~0.8.2", "meshoptimizer": "~1.1.1" } }, "sha512-O2Uy8Cj4Nonr8dWUUbifMdPe8B0Mq7EdOHb89S4+kjUw/KhbjTZrUuYlrQ1bpUKG+EP9QJnN7qNxbHGlGoLHMA=="], + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + "@types/webxr": ["@types/webxr@0.5.24", "", {}, "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@7.18.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/type-utils": "7.18.0", "@typescript-eslint/utils": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "peerDependencies": { "@typescript-eslint/parser": "^7.0.0", "eslint": "^8.56.0" } }, "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw=="], @@ -968,6 +995,10 @@ "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + "@use-gesture/core": ["@use-gesture/core@10.3.1", "", {}, "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw=="], + + "@use-gesture/react": ["@use-gesture/react@10.3.1", "", { "dependencies": { "@use-gesture/core": "10.3.1" }, "peerDependencies": { "react": ">= 16.8.0" } }, "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g=="], + "@vitejs/plugin-react": ["@vitejs/plugin-react@3.1.0", "", { "dependencies": { "@babel/core": "^7.20.12", "@babel/plugin-transform-react-jsx-self": "^7.18.6", "@babel/plugin-transform-react-jsx-source": "^7.19.6", "magic-string": "^0.27.0", "react-refresh": "^0.14.0" }, "peerDependencies": { "vite": "^4.1.0-beta.0" } }, "sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g=="], "JSONStream": ["JSONStream@1.3.5", "", { "dependencies": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" }, "bin": { "JSONStream": "./bin.js" } }, "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ=="], @@ -1038,6 +1069,8 @@ "better-sqlite3": ["better-sqlite3@12.9.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ=="], + "bidi-js": ["bidi-js@1.0.3", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="], + "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="], @@ -1054,7 +1087,7 @@ "browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="], - "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], @@ -1078,6 +1111,8 @@ "camelcase-keys": ["camelcase-keys@6.2.2", "", { "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" } }, "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg=="], + "camera-controls": ["camera-controls@3.1.2", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA=="], + "caniuse-lite": ["caniuse-lite@1.0.30001790", "", {}, "sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], @@ -1154,6 +1189,8 @@ "cron-parser": ["cron-parser@4.9.0", "", { "dependencies": { "luxon": "^3.2.1" } }, "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q=="], + "cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="], + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], @@ -1206,6 +1243,8 @@ "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="], + "detect-gpu": ["detect-gpu@5.0.70", "", { "dependencies": { "webgl-constants": "^1.1.1" } }, "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w=="], + "detect-indent": ["detect-indent@6.1.0", "", {}, "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA=="], "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], @@ -1228,6 +1267,8 @@ "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + "draco3d": ["draco3d@1.5.7", "", {}, "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ=="], + "drizzle-kit": ["drizzle-kit@0.31.10", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.25.4", "tsx": "^4.21.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw=="], "drizzle-orm": ["drizzle-orm@0.45.2", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q=="], @@ -1360,6 +1401,8 @@ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fflate": ["fflate@0.6.10", "", {}, "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg=="], + "file-entry-cache": ["file-entry-cache@6.0.1", "", { "dependencies": { "flat-cache": "^3.0.4" } }, "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="], "file-type": ["file-type@22.0.1", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.5", "token-types": "^6.1.2", "uint8array-extras": "^1.5.0" } }, "sha512-ww5Mhre0EE+jmBvOXTmXAbEMuZE7uX4a3+oRCQFNj8w++g3ev913N6tXQz0XTXbueQ5TWQfm6BdaViEHHn8bhA=="], @@ -1444,6 +1487,8 @@ "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], + "glsl-noise": ["glsl-noise@0.0.0", "", {}, "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w=="], + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], @@ -1478,6 +1523,8 @@ "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + "hls.js": ["hls.js@1.6.16", "", {}, "sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA=="], + "hono": ["hono@4.12.15", "", {}, "sha512-qM0jDhFEaCBb4TxoW7f53Qrpv9RBiayUHo0S52JudprkhvpjIrGoU1mnnr29Fvd1U335ZFPZQY1wlkqgfGXyLg=="], "hono-basic-example": ["hono-basic-example@workspace:examples/hono"], @@ -1498,6 +1545,8 @@ "image-size": ["image-size@2.0.2", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w=="], + "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="], @@ -1606,6 +1655,8 @@ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + "its-fine": ["its-fine@2.0.0", "", { "dependencies": { "@types/react-reconciler": "^0.28.9" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng=="], + "jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -1638,6 +1689,8 @@ "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + "lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="], + "light-my-request": ["light-my-request@6.6.0", "", { "dependencies": { "cookie": "^1.0.1", "process-warning": "^4.0.0", "set-cookie-parser": "^2.6.0" } }, "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A=="], "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], @@ -1702,6 +1755,8 @@ "luxon": ["luxon@3.7.2", "", {}, "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew=="], + "maath": ["maath@0.10.8", "", { "peerDependencies": { "@types/three": ">=0.134.0", "three": ">=0.134.0" } }, "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g=="], + "magic-string": ["magic-string@0.27.0", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" } }, "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA=="], "map-obj": ["map-obj@4.3.0", "", {}, "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ=="], @@ -1754,6 +1809,10 @@ "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + "meshline": ["meshline@3.3.1", "", { "peerDependencies": { "three": ">=0.137" } }, "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ=="], + + "meshoptimizer": ["meshoptimizer@1.1.1", "", {}, "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g=="], + "methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="], "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], @@ -1984,6 +2043,8 @@ "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + "potpack": ["potpack@1.0.2", "", {}, "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="], + "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], "preferred-pm": ["preferred-pm@3.1.4", "", { "dependencies": { "find-up": "^5.0.0", "find-yarn-workspace-root2": "1.2.16", "path-exists": "^4.0.0", "which-pm": "^2.2.0" } }, "sha512-lEHd+yEm22jXdCphDrkvIJQU66EuLojPPtvZkpKIkiD+l0DMThF/niqZKJSoU8Vl7iuvtmzyMhir9LdVy5WMnA=="], @@ -1996,6 +2057,8 @@ "process-warning": ["process-warning@5.0.0", "", {}, "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA=="], + "promise-worker-transferable": ["promise-worker-transferable@1.0.4", "", { "dependencies": { "is-promise": "^2.1.0", "lie": "^3.0.2" } }, "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw=="], + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], @@ -2038,6 +2101,8 @@ "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + "react-use-measure": ["react-use-measure@2.1.7", "", { "peerDependencies": { "react": ">=16.13", "react-dom": ">=16.13" }, "optionalPeers": ["react-dom"] }, "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg=="], + "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], "read-pkg": ["read-pkg@5.2.0", "", { "dependencies": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", "parse-json": "^5.0.0", "type-fest": "^0.6.0" } }, "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg=="], @@ -2210,6 +2275,10 @@ "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], + "stats-gl": ["stats-gl@2.4.2", "", { "dependencies": { "@types/three": "*", "three": "^0.170.0" } }, "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ=="], + + "stats.js": ["stats.js@0.17.0", "", {}, "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw=="], + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="], @@ -2250,6 +2319,8 @@ "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + "suspend-react": ["suspend-react@0.1.3", "", { "peerDependencies": { "react": ">=17.0" } }, "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ=="], + "tailwind-merge": ["tailwind-merge@2.6.1", "", {}, "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ=="], "tailwindcss": ["tailwindcss@4.2.4", "", {}, "sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA=="], @@ -2272,6 +2343,12 @@ "thread-stream": ["thread-stream@4.0.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA=="], + "three": ["three@0.185.0", "", {}, "sha512-+yRrcRO2iZa8uzvNNl0d7cL4huhgKgBvVJ0njcTe8xFqZ6DMAFZdCKDP91SEAuj25bNAj7k1QQdf+srZywVK6w=="], + + "three-mesh-bvh": ["three-mesh-bvh@0.8.3", "", { "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg=="], + + "three-stdlib": ["three-stdlib@2.36.1", "", { "dependencies": { "@types/draco3d": "^1.4.0", "@types/offscreencanvas": "^2019.6.4", "@types/webxr": "^0.5.2", "draco3d": "^1.4.1", "fflate": "^0.6.9", "potpack": "^1.0.1" }, "peerDependencies": { "three": ">=0.128.0" } }, "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg=="], + "through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="], "tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], @@ -2294,6 +2371,12 @@ "trim-newlines": ["trim-newlines@3.0.1", "", {}, "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw=="], + "troika-three-text": ["troika-three-text@0.52.4", "", { "dependencies": { "bidi-js": "^1.0.2", "troika-three-utils": "^0.52.4", "troika-worker-utils": "^0.52.0", "webgl-sdf-generator": "1.1.1" }, "peerDependencies": { "three": ">=0.125.0" } }, "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg=="], + + "troika-three-utils": ["troika-three-utils@0.52.4", "", { "peerDependencies": { "three": ">=0.125.0" } }, "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A=="], + + "troika-worker-utils": ["troika-worker-utils@0.52.0", "", {}, "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw=="], + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], "ts-api-utils": ["ts-api-utils@1.4.3", "", { "peerDependencies": { "typescript": ">=4.2.0" } }, "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw=="], @@ -2308,6 +2391,8 @@ "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="], + "tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "^4.3.2" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="], + "turbo": ["turbo@2.9.6", "", { "optionalDependencies": { "@turbo/darwin-64": "2.9.6", "@turbo/darwin-arm64": "2.9.6", "@turbo/linux-64": "2.9.6", "@turbo/linux-arm64": "2.9.6", "@turbo/windows-64": "2.9.6", "@turbo/windows-arm64": "2.9.6" }, "bin": { "turbo": "bin/turbo" } }, "sha512-+v2QJey7ZUeUiuigkU+uFfklvNUyPI2VO2vBpMYJA+a1hKFLFiKtUYlRHdb3P9CrAvMzi0upbjI4WT+zKtqkBg=="], "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], @@ -2364,6 +2449,8 @@ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + "utility-types": ["utility-types@3.11.0", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="], + "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], "uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="], @@ -2386,6 +2473,10 @@ "web": ["web@workspace:apps/web"], + "webgl-constants": ["webgl-constants@1.1.1", "", {}, "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="], + + "webgl-sdf-generator": ["webgl-sdf-generator@1.1.1", "", {}, "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA=="], + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], @@ -2426,6 +2517,8 @@ "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], + "zustand": ["zustand@5.0.14", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g=="], + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -2518,6 +2611,8 @@ "@types/serve-static/@types/node": ["@types/node@24.6.2", "", { "dependencies": { "undici-types": "~7.13.0" } }, "sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang=="], + "@types/three/fflate": ["fflate@0.8.3", "", {}, "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA=="], + "@types/ws/@types/node": ["@types/node@24.6.2", "", { "dependencies": { "undici-types": "~7.13.0" } }, "sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], @@ -2528,6 +2623,8 @@ "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + "body-parser/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "bun-types/@types/node": ["@types/node@24.6.2", "", { "dependencies": { "undici-types": "~7.13.0" } }, "sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang=="], @@ -2598,6 +2695,8 @@ "postcss-nested/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "promise-worker-transferable/is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="], + "raw-body/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], @@ -2622,10 +2721,14 @@ "spawndamnit/cross-spawn": ["cross-spawn@5.1.0", "", { "dependencies": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A=="], + "stats-gl/three": ["three@0.170.0", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="], + "tsx/esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], "tty-table/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "tunnel-rat/zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="], + "type-is/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], "web/lucide-react": ["lucide-react@0.468.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } }, "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA=="], From a8d03fd9ac1cf4fc92d37ad1aac57c6feb5aee87 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Jun 2026 21:54:09 +0000 Subject: [PATCH 05/11] feat(docs): showcase @getvision/server with a real span/log example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the Express snippet with the flagship @getvision/server (Elysia) API: the handler adds a span, wide-event context and a log, and the dashboard mock maps 1:1 — root request span plus the db.select / enrich.profiles spans, with the log carrying the user.plan context. Makes clear that detail comes from instrumenting, not magic. --- apps/docs/app/(home)/_components/showcase.tsx | 122 ++++++++++++------ 1 file changed, 81 insertions(+), 41 deletions(-) diff --git a/apps/docs/app/(home)/_components/showcase.tsx b/apps/docs/app/(home)/_components/showcase.tsx index 460fcde..0603081 100644 --- a/apps/docs/app/(home)/_components/showcase.tsx +++ b/apps/docs/app/(home)/_components/showcase.tsx @@ -10,18 +10,12 @@ const reveal = { transition: { duration: 0.5, ease: "easeOut" }, } as const; -// A stylised trace waterfall — offsets/widths are % of the request duration. +// The spans below map 1:1 to the span() calls in the code on the left. +// Offsets/widths are % of the request duration. const SPANS = [ { label: "GET /users", ms: "142ms", left: 0, width: 100, depth: 0 }, - { - label: "db.query · select users", - ms: "38ms", - left: 8, - width: 27, - depth: 1, - }, - { label: "cache.get", ms: "4ms", left: 36, width: 4, depth: 1 }, - { label: "serialize", ms: "6ms", left: 88, width: 8, depth: 1 }, + { label: "db.select", ms: "38ms", left: 8, width: 27, depth: 1 }, + { label: "enrich.profiles", ms: "54ms", left: 36, width: 38, depth: 1 }, ]; export function Showcase() { @@ -29,15 +23,16 @@ export function Showcase() {

    - Two lines in. Full visibility out. + Add a span. Watch it appear.

    - Mount the adapter, then open the dashboard — every request becomes a - trace you can read, replay and debug. + Every request is traced automatically. Drop span(), + context and logs where you want more detail — and see exactly what + ran, in order, with timings.

    -
    +
    {/* Code card */}
    @@ -47,43 +42,86 @@ export function Showcase() { - server.ts + users.module.ts
    -
    +            
                   
    -                
    -                  {"// 1. add the adapter"}
    -                
    -                {"\n"}
                     import
                     
    -                  {" { visionAdapter } "}
    +                  {" { createModule } "}
                     
                     from
                     
    -                  {" '@getvision/adapter-express'"}
    +                  {" '@getvision/server'"}
                     
                     {"\n\n"}
    -                
    -                  {"// 2. mount it on the app you already have"}
    +                export const
    +                {" users = "}
    +                createModule
    +                ({"{ "}
    +                prefix
    +                : 
    +                {"'/users'"}
    +                {" })"}
    +                {"\n"}
    +                {"  ."}
    +                get
    +                
    +                  {"('/', ({ span, addContext, logger }) => {"}
                     
                     {"\n"}
    -                app.
    -                use
    -                (
    -                visionAdapter
    +                {"    "}
    +                addContext
                     ({"{ "}
    -                port
    +                {"'user.plan'"}
                     : 
    -                9500
    -                {" }))"}
    +                {"'pro'"}
    +                {" })"}
                     {"\n\n"}
    -                
    -                
    -                  {" dashboard live at "}
    +                {"    "}
    +                const
    +                {" rows = "}
    +                span
    +                (
    +                {"'db.select'"}
    +                , {"{ "}
    +                {"'db.table'"}
    +                : 
    +                {"'users'"}
    +                {" }, () =>"}
    +                {"\n"}
    +                
    +                  {"      db.select().from(users).all()"}
    +                
    +                {"\n"}
    +                {"    )"}
    +                {"\n"}
    +                {"    "}
    +                const
    +                {" data = "}
    +                span
    +                (
    +                {"'enrich.profiles'"}
    +                
    +                  {", {}, () => enrich(rows))"}
                     
    -                localhost:9500
    +                {"\n\n"}
    +                {"    "}
    +                logger
    +                .
    +                info
    +                (
    +                {"'loaded users'"}
    +                , {"{ "}
    +                count
    +                : rows.length {"}"})
    +                {"\n"}
    +                {"    "}
    +                return
    +                {" data"}
    +                {"\n"}
    +                {"  })"}
                   
                 
    @@ -137,7 +175,7 @@ export function Showcase() { {SPANS.map((s) => (
    {s.label} @@ -155,13 +193,15 @@ export function Showcase() { ))}
    - {/* log line */} + {/* log line carrying wide-event context */}
    - {" "} + + INFO + {" "} + loaded users{" "} - user.id=123 plan= - pro · request - completed + count=12 user.plan= + pro
    From 9e800b118775fac24c68f884c60880034f4db142 Mon Sep 17 00:00:00 2001 From: Ihor Kolobanov Date: Wed, 1 Jul 2026 08:21:28 +0200 Subject: [PATCH 06/11] Upgrade fumadocs and README.md --- CLAUDE.md | 27 +- apps/docs/app/docs/[[...slug]]/page.tsx | 5 +- apps/docs/app/llms.txt/route.ts | 42 ++ apps/docs/lib/source.ts | 8 +- apps/docs/package.json | 13 +- apps/docs/source.config.ts | 15 +- apps/docs/tsconfig.json | 28 +- bun.lock | 283 ++++++--- packages/server/README.md | 801 ++++++++++++------------ 9 files changed, 701 insertions(+), 521 deletions(-) create mode 100644 apps/docs/app/llms.txt/route.ts diff --git a/CLAUDE.md b/CLAUDE.md index 202f649..5ad0a2c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -842,22 +842,31 @@ bun run build ### @getvision/server -**Purpose:** Meta-framework built on Hono with built-in observability +**Purpose:** Meta-framework built on Elysia with built-in observability **Key features:** -- Service builder pattern -- Event bus (BullMQ) -- Cron jobs (BullMQ repeatable jobs) -- Built-in Vision integration +- Module pattern: `createVision()` + `createModule({ prefix }).use(defineEvents(...)).get(...)` +- Per-request context helpers: `span`, `addContext`, `emit`, `traceId` +- Standard Schema validation (Zod / Valibot / TypeBox via re-exported `t`) +- Type-safe pub/sub events (`defineEvents`) with trace context propagation +- Cron jobs via BullMQ repeatable jobs (`defineCrons`) +- Per-endpoint rate limiting (`rateLimit`) +- OTLP trace export (`OtlpTraceExporter`) +- Eden Treaty ready — `export type AppType = typeof app` +- Graceful shutdown — `ready(app)` / `close(app)` (also `app.close()`, auto-registered with `bun --hot`) + +**Public exports** (from `src/vision-app.ts`): +`createVision`, `createModule`, `defineEvents`, `defineCrons`, `rateLimit`, `onEvent`, `onEvents`, `MemoryRateLimitStore`, `getVisionContext`, `ready`, `close`, `EventBus`, `t` (Elysia/TypeBox). **Dependencies:** -- `hono` - Base framework -- `@hono/node-server` - Node.js adapter +- `elysia` - Base framework (Bun-first) - `bullmq` - Job queue and event bus - `ioredis` - Redis client -- `zod` - Validation (required for server) +- `zod` - Validation (commonly used; also supports Valibot and TypeBox via Standard Schema) -**Note:** Exports TypeScript source (`exports: "./src/index.ts"`), not compiled +**Note:** Exports TypeScript source (`exports: "./src/index.ts"`), not compiled. + +**Migration:** The pre-1.0 Hono-based `Vision` class and `app.service(...).endpoint(...)` ServiceBuilder pattern are gone. See `apps/docs/content/docs/server/migration.mdx` for the old → new mapping. ### @getvision/adapter-express diff --git a/apps/docs/app/docs/[[...slug]]/page.tsx b/apps/docs/app/docs/[[...slug]]/page.tsx index 9b6d208..2c39309 100644 --- a/apps/docs/app/docs/[[...slug]]/page.tsx +++ b/apps/docs/app/docs/[[...slug]]/page.tsx @@ -4,7 +4,7 @@ import { DocsDescription, DocsPage, DocsTitle, -} from 'fumadocs-ui/page'; +} from 'fumadocs-ui/layouts/docs/page'; import { notFound } from 'next/navigation'; import { getMDXComponents } from '@/mdx-components'; import type { Metadata } from 'next'; @@ -25,7 +25,8 @@ export default async function Page(props: PageProps<'/docs/[[...slug]]'>) { diff --git a/apps/docs/app/llms.txt/route.ts b/apps/docs/app/llms.txt/route.ts new file mode 100644 index 0000000..93d0859 --- /dev/null +++ b/apps/docs/app/llms.txt/route.ts @@ -0,0 +1,42 @@ +import { source } from '@/lib/source'; + +export const revalidate = false; + +/** + * Short LLM-friendly index of the documentation, per the llms.txt spec + * (https://llmstxt.org/). Each page is listed as a markdown link with its + * frontmatter description. The full text of every page lives at + * `/llms-full.txt`. + */ +export async function GET() { + const baseUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'https://getvision.dev'; + + const pages = source.getPages(); + const lines: string[] = [ + '# Vision', + '', + '> Universal observability dashboard for API development — built-in tracing,', + "> logs, and an API explorer for Express, Fastify, Hono, Next.js, or Vision's", + '> own Elysia-based meta-framework.', + '', + '## Docs', + '', + ]; + + for (const page of pages) { + const title = page.data.title; + const description = page.data.description; + const url = `${baseUrl}${page.url}`; + lines.push( + description + ? `- [${title}](${url}): ${description}` + : `- [${title}](${url})` + ); + } + + lines.push('', '## Full content', '', `- [Full documentation](${baseUrl}/llms-full.txt)`); + + return new Response(lines.join('\n'), { + headers: { 'content-type': 'text/plain; charset=utf-8' }, + }); +} diff --git a/apps/docs/lib/source.ts b/apps/docs/lib/source.ts index 5895211..783a100 100644 --- a/apps/docs/lib/source.ts +++ b/apps/docs/lib/source.ts @@ -1,5 +1,5 @@ -import { docs } from '@/.source'; -import { type InferPageType, loader } from 'fumadocs-core/source'; +import { docs } from 'collections/server'; +import { loader } from 'fumadocs-core/source'; import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons'; // See https://fumadocs.dev/docs/headless/source-api for more info @@ -9,7 +9,7 @@ export const source = loader({ plugins: [lucideIconsPlugin()], }); -export function getPageImage(page: InferPageType) { +export function getPageImage(page: (typeof source)['$inferPage']) { const segments = [...page.slugs, 'image.png']; return { @@ -18,7 +18,7 @@ export function getPageImage(page: InferPageType) { }; } -export async function getLLMText(page: InferPageType) { +export async function getLLMText(page: (typeof source)['$inferPage']) { const processed = await page.data.getText('processed'); return `# ${page.data.title} (${page.url}) diff --git a/apps/docs/package.json b/apps/docs/package.json index 5c1af2d..03e81a6 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -13,15 +13,16 @@ "@react-three/drei": "^10.7.7", "@react-three/fiber": "^9.6.1", "cnfast": "^0.0.8", - "fumadocs-core": "15.8.5", - "fumadocs-mdx": "12.0.3", - "fumadocs-ui": "15.8.5", - "lucide-react": "^0.544.0", "motion": "^11.18.1", - "next": "15.5.4", + "next": "16.2.7", "react": "catalog:", "react-dom": "catalog:", - "three": "^0.185.0" + "three": "^0.185.0", + "lucide-react": "^0.544.0", + "fumadocs-ui": "16.9.3", + "fumadocs-core": "16.9.3", + "fumadocs-mdx": "15.0.10", + "zod": "^4.4.3" }, "devDependencies": { "@types/node": "24.6.2", diff --git a/apps/docs/source.config.ts b/apps/docs/source.config.ts index d2e968b..741bde6 100644 --- a/apps/docs/source.config.ts +++ b/apps/docs/source.config.ts @@ -1,22 +1,13 @@ -import { - defineConfig, - defineDocs, - frontmatterSchema, - metaSchema, -} from 'fumadocs-mdx/config'; +import { defineConfig, defineDocs } from 'fumadocs-mdx/config'; -// You can customise Zod schemas for frontmatter and `meta.json` here -// see https://fumadocs.dev/docs/mdx/collections +// See https://fumadocs.dev/docs/mdx/collections export const docs = defineDocs({ + dir: 'content/docs', docs: { - schema: frontmatterSchema, postprocess: { includeProcessedMarkdown: true, }, }, - meta: { - schema: metaSchema, - }, }); export default defineConfig({ diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 4fd260f..50000d4 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -2,7 +2,11 @@ "compilerOptions": { "baseUrl": ".", "target": "ESNext", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -13,11 +17,15 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "incremental": true, "paths": { - "@/.source": ["./.source/index.ts"], - "@/*": ["./*"] + "@/*": [ + "./*" + ], + "collections/*": [ + "./.source/*" + ] }, "plugins": [ { @@ -25,6 +33,14 @@ } ] }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } diff --git a/bun.lock b/bun.lock index 84b8985..d0e7d78 100644 --- a/bun.lock +++ b/bun.lock @@ -21,15 +21,16 @@ "@react-three/drei": "^10.7.7", "@react-three/fiber": "^9.6.1", "cnfast": "^0.0.8", - "fumadocs-core": "15.8.5", - "fumadocs-mdx": "12.0.3", - "fumadocs-ui": "15.8.5", + "fumadocs-core": "16.9.3", + "fumadocs-mdx": "15.0.10", + "fumadocs-ui": "16.9.3", "lucide-react": "^0.544.0", "motion": "^11.18.1", - "next": "15.5.4", + "next": "16.2.7", "react": "catalog:", "react-dom": "catalog:", "three": "^0.185.0", + "zod": "^4.4.3", }, "devDependencies": { "@tailwindcss/postcss": "^4.1.14", @@ -457,57 +458,57 @@ "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "^3.3.2", "get-tsconfig": "^4.7.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="], - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="], "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="], @@ -539,7 +540,7 @@ "@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="], - "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.2", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA=="], + "@fumadocs/tailwind": ["@fumadocs/tailwind@0.0.5", "", { "peerDependencies": { "@tailwindcss/oxide": "^4.0.0", "tailwindcss": "^4.0.0" }, "optionalPeers": ["@tailwindcss/oxide", "tailwindcss"] }, "sha512-ENKPWUDRmriccsrUDE4bDBq3FNr/ms3BP2rWlsAEMV1yP23pcCaan+ceGfeBUsAQjw7sj9Q3R4Kl3g/TCStPzQ=="], "@getvision/adapter-express": ["@getvision/adapter-express@workspace:packages/adapter-express"], @@ -645,23 +646,23 @@ "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="], - "@next/env": ["@next/env@15.5.4", "", {}, "sha512-27SQhYp5QryzIT5uO8hq99C69eLQ7qkzkDPsk3N+GuS2XgOgoYEeOav7Pf8Tn4drECOVDsDg8oj+/DVy8qQL2A=="], + "@next/env": ["@next/env@16.2.7", "", {}, "sha512-tMJizPlj6ZYpBMMdK8S0LJufrP4QTdR6pcv9KQ/bVETPAmg0j1mlHE9G2c38UyGHxoBapgwuj7XjbGJ2RcDFOg=="], - "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-nopqz+Ov6uvorej8ndRX6HlxCYWCO3AHLfKK2TYvxoSB2scETOcfm/HSS3piPqc3A+MUgyHoqE6je4wnkjfrOA=="], + "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.2.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vm1EDI/pVaBNNiychmxk3fft+OhQPVD9cIM/tReLZIQ3TfQ4kqI9DwKk00dzuS1ulC7icbrzCFrmRRlk9PfNdw=="], - "@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-QOTCFq8b09ghfjRJKfb68kU9k2K+2wsC4A67psOiMn849K9ZXgCSRQr0oVHfmKnoqCbEmQWG1f2h1T2vtJJ9mA=="], + "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.2.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-O3IRSv1ZBL1zs0WrIgefTEcTKFVn+ryxBNe54erJ6KsD+2f/Mmt7g2jOYh8PSBdUwPtKQJuCsTMlZ7tIu2AcsQ=="], - "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-eRD5zkts6jS3VfE/J0Kt1VxdFqTnMc3QgO5lFE5GKN3KDI/uUpSyK3CjQHmfEkYR4wCOl0R0XrsjpxfWEA++XA=="], + "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.2.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-Re6PZtjBDd0aMU+VcZcC/PrIvj4WhrjDYtMhhCVQamWN4L90EVP0pcEOBQD25prSlw7OzNw5QpHLWMilRLsRNw=="], - "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-TOK7iTxmXFc45UrtKqWdZ1shfxuL4tnVAOuuJK4S88rX3oyVV4ZkLjtMT85wQkfBrOOvU55aLty+MV8xmcJR8A=="], + "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.2.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-qyogG9QtBzWxgJfeGBvOEHI3851gTfCF3wLZ5RDLTBJGAmE9p1qDwKCOdrBrvBzRvYDT+gUDp72pzlSEfAXgNA=="], - "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.4", "", { "os": "linux", "cpu": "x64" }, "sha512-7HKolaj+481FSW/5lL0BcTkA4Ueam9SPYWyN/ib/WGAFZf0DGAN8frNpNZYFHtM4ZstrHZS3LY3vrwlIQfsiMA=="], + "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.2.7", "", { "os": "linux", "cpu": "x64" }, "sha512-Vhe4ZDuBpmMogrGi5D4R2Kq4JAQlj6+wvgaFYy31zfES0zPmt6TLA+cuYpM/OLrPZjo2MYQTHVqNUSCR6+fDZQ=="], - "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.4", "", { "os": "linux", "cpu": "x64" }, "sha512-nlQQ6nfgN0nCO/KuyEUwwOdwQIGjOs4WNMjEUtpIQJPR2NUfmGpW2wkJln1d4nJ7oUzd1g4GivH5GoEPBgfsdw=="], + "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.2.7", "", { "os": "linux", "cpu": "x64" }, "sha512-srvian89JahFLw1YLBEuhvPJ0DO5lpUeJQMXy4xYo7g628ZlNgXdNkqoxSAv9OYrBfByh6vxISMwW/mRbzCY+g=="], - "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-PcR2bN7FlM32XM6eumklmyWLLbu2vs+D7nJX8OAIoWy69Kef8mfiN4e8TUv2KohprwifdpFKPzIP1njuCjD0YA=="], + "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.2.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-GX3wvLpULFuRFJzwHaKfm7QZJ18F4ZSuxlPJ96BoBglCzBmdSjyeBKF+ZhWhvL/ckxNfLnNa7bsObO2ipYpszw=="], - "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.4", "", { "os": "win32", "cpu": "x64" }, "sha512-1ur2tSHZj8Px/KMAthmuI9FMp/YFusMMGoRNJaRZMOlSkgvLjzosSdQI0cJAKogdHl3qXUQKL9MGaYvKwA7DXg=="], + "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.2.7", "", { "os": "win32", "cpu": "x64" }, "sha512-J4WlM72NMk076Qsg0jTdK3SNXatlSdnjW7L7oNGLst1tAGjHrJh/FYi+pw9wyIjEtGRKDNzD0zuiY16oWYWVaw=="], "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], @@ -815,21 +816,19 @@ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.60.2", "", { "os": "win32", "cpu": "x64" }, "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA=="], - "@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], + "@shikijs/core": ["@shikijs/core@4.3.0", "", { "dependencies": { "@shikijs/primitive": "4.3.0", "@shikijs/types": "4.3.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-EooU3i9F6IAE8kEu+AnGf9DFZWkQBZ+hJn3tLVbsH+61mtQiva5biai66fAA6nvFPXkLgvrh7BrR7YcJU83xQQ=="], - "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.3.0", "", { "dependencies": { "@shikijs/types": "4.3.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.6" } }, "sha512-hTv/KiFf2tpiqlACPiztGGurEARWIutB8YUhcrA1pUC7VzzwKO+g5crUocrLztrZ5ro5Z4hbXg7bYclETn3gSQ=="], - "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.3.0", "", { "dependencies": { "@shikijs/types": "4.3.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1vMdN3gHfnKfLYwecUI2ITJI4RhHt96xEaJumVn7Heb0IlJ8WQMIH0Voak+2j22BpSNKdnOfB/pCTPnPm2gq7A=="], - "@shikijs/langs": ["@shikijs/langs@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg=="], + "@shikijs/langs": ["@shikijs/langs@4.3.0", "", { "dependencies": { "@shikijs/types": "4.3.0" } }, "sha512-rnlqFbBRSys9bT4gl/5rw9RnS0W/I84ZldXPkO7cvlEMoV85TyF/aU01N7/NbSR776RNLjrJKjfFUXJR6wN1Cg=="], - "@shikijs/rehype": ["@shikijs/rehype@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@types/hast": "^3.0.4", "hast-util-to-string": "^3.0.1", "shiki": "3.23.0", "unified": "^11.0.5", "unist-util-visit": "^5.1.0" } }, "sha512-GepKJxXHbXFfAkiZZZ+4V7x71Lw3s0ALYmydUxJRdvpKjSx9FOMSaunv6WRLFBXR6qjYerUq1YZQno+2gLEPwA=="], + "@shikijs/primitive": ["@shikijs/primitive@4.3.0", "", { "dependencies": { "@shikijs/types": "4.3.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-CPkz64PTa5diRW1ggzMZH9VM/du4RNChYgVtgqrFcgruvIybmCvySv8GkiHSczUHXYuuR8TdKEwFx+UnZMpgdg=="], - "@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], + "@shikijs/themes": ["@shikijs/themes@4.3.0", "", { "dependencies": { "@shikijs/types": "4.3.0" } }, "sha512-Avgt05YiT+Y3prjIc9lmQxhJzHBcCfR6cjiFW4OyaMBbt2A6trX5rfjUzx+Vj/mE9qpArYjatnqo9XPjQNW/AQ=="], - "@shikijs/transformers": ["@shikijs/transformers@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/types": "3.23.0" } }, "sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ=="], - - "@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], + "@shikijs/types": ["@shikijs/types@4.3.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-oc8b9U2SYvofKZk8e/737nIX0qwf6eV2vHFATeObAu7r+mUVpLs8Re0BmVkIjAWAYgkmG/CzLNo7rzuBzRu/wQ=="], "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], @@ -1129,7 +1128,7 @@ "chardet": ["chardet@0.7.0", "", {}, "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="], - "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], + "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], @@ -1291,6 +1290,8 @@ "enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="], + "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], @@ -1313,7 +1314,7 @@ "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], - "esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], @@ -1441,11 +1442,11 @@ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], - "fumadocs-core": ["fumadocs-core@15.8.5", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.6.2", "@orama/orama": "^3.1.14", "@shikijs/rehype": "^3.13.0", "@shikijs/transformers": "^3.13.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "image-size": "^2.0.2", "negotiator": "^1.0.0", "npm-to-yarn": "^3.0.1", "path-to-regexp": "^8.3.0", "react-remove-scroll": "^2.7.1", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^3.13.0", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "@mixedbread/sdk": "^0.19.0", "@oramacloud/client": "1.x.x || 2.x.x", "@tanstack/react-router": "1.x.x", "@types/react": "*", "algoliasearch": "5.x.x", "lucide-react": "*", "next": "14.x.x || 15.x.x", "react": "18.x.x || 19.x.x", "react-dom": "18.x.x || 19.x.x", "react-router": "7.x.x", "waku": "^0.26.0" }, "optionalPeers": ["@mixedbread/sdk", "@oramacloud/client", "@tanstack/react-router", "@types/react", "algoliasearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku"] }, "sha512-hyJtKGuB2J/5y7tDfI1EnGMKlNbSXM5N5cpwvgCY0DcBJwFMDG/GpSpaVRzh3aWy67pAYDZFIwdtbKXBa/q5bg=="], + "fumadocs-core": ["fumadocs-core@16.9.3", "", { "dependencies": { "@orama/orama": "^3.1.18", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "js-yaml": "^4.1.1", "mdast-util-mdx": "^3.0.0", "mdast-util-to-markdown": "^2.1.2", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^4.1.0", "tinyglobby": "^0.2.16", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "@mdx-js/mdx": "*", "@mixedbread/sdk": "0.x.x", "@orama/core": "1.x.x", "@oramacloud/client": "2.x.x", "@tanstack/react-router": "1.x.x", "@types/estree-jsx": "*", "@types/hast": "*", "@types/mdast": "*", "@types/react": "*", "algoliasearch": "5.x.x", "flexsearch": "*", "lucide-react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "7.x.x", "waku": "*", "zod": "4.x.x" }, "optionalPeers": ["@mdx-js/mdx", "@mixedbread/sdk", "@orama/core", "@oramacloud/client", "@tanstack/react-router", "@types/estree-jsx", "@types/hast", "@types/mdast", "@types/react", "algoliasearch", "flexsearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku", "zod"] }, "sha512-8RVzKnzBJR5o+tJCccY28ntekfMQYBoYiz7alnYb/d9YJc+XpnsINzTl63lQ1eBMZ9gdhm2MqRtgUjh/8rUrbw=="], - "fumadocs-mdx": ["fumadocs-mdx@12.0.3", "", { "dependencies": { "@mdx-js/mdx": "^3.1.1", "@standard-schema/spec": "^1.0.0", "chokidar": "^4.0.3", "esbuild": "^0.25.10", "estree-util-value-to-estree": "^3.4.0", "js-yaml": "^4.1.0", "lru-cache": "^11.2.2", "mdast-util-to-markdown": "^2.1.2", "picocolors": "^1.1.1", "remark-mdx": "^3.1.1", "remark-parse": "^11.0.0", "tinyexec": "^1.0.1", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "zod": "^4.1.11" }, "peerDependencies": { "@fumadocs/mdx-remote": "^1.4.0", "fumadocs-core": "^14.0.0 || ^15.0.0", "next": "^15.3.0", "react": "*", "vite": "6.x.x || 7.x.x" }, "optionalPeers": ["@fumadocs/mdx-remote", "next", "react", "vite"], "bin": { "fumadocs-mdx": "dist/bin.js" } }, "sha512-OYqbHSmzkejG+iUMlZJJOitaVbCgBdo/REc/9Sq1WaZ1vq6bH9PCFU0cKJlRdHbQSGRfVg5EJJy5uKy5+iNFGQ=="], + "fumadocs-mdx": ["fumadocs-mdx@15.0.10", "", { "dependencies": { "@mdx-js/mdx": "^3.1.1", "@standard-schema/spec": "^1.1.0", "chokidar": "^5.0.0", "esbuild": "^0.28.0", "estree-util-value-to-estree": "^3.5.0", "js-yaml": "^4.1.1", "mdast-util-mdx": "^3.0.0", "picocolors": "^1.1.1", "picomatch": "^4.0.4", "tinyexec": "^1.2.2", "tinyglobby": "^0.2.16", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3", "zod": "^4.4.3" }, "peerDependencies": { "@types/mdast": "*", "@types/mdx": "*", "@types/react": "*", "fumadocs-core": "^16.7.0", "mdast-util-directive": "*", "next": "^15.3.0 || ^16.0.0", "react": "^19.2.0", "rolldown": "*", "vite": "7.x.x || 8.x.x" }, "optionalPeers": ["@types/mdast", "@types/mdx", "@types/react", "mdast-util-directive", "next", "react", "rolldown", "vite"], "bin": { "fumadocs-mdx": "./bin.js" } }, "sha512-kH3S7ESS9yXTAaCkA8dDugsCK/MbnpgyZ5qBEL7cWoavV0O/T4+4YTYFkvNknz7cw+T/r+OG0p2BvlVhkk4fww=="], - "fumadocs-ui": ["fumadocs-ui@15.8.5", "", { "dependencies": { "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-direction": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-presence": "^1.1.5", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", "fumadocs-core": "15.8.5", "lodash.merge": "^4.6.2", "next-themes": "^0.4.6", "postcss-selector-parser": "^7.1.0", "react-medium-image-zoom": "^5.4.0", "scroll-into-view-if-needed": "^3.1.0", "tailwind-merge": "^3.3.1" }, "peerDependencies": { "@types/react": "*", "next": "14.x.x || 15.x.x", "react": "18.x.x || 19.x.x", "react-dom": "18.x.x || 19.x.x", "tailwindcss": "^3.4.14 || ^4.0.0" }, "optionalPeers": ["@types/react", "next", "tailwindcss"] }, "sha512-9pyB+9rOOsrFnmmZ9xREp/OgVhyaSq2ocEpqTNbeQ7tlJ6JWbdFWfW0C9lRXprQEB6DJWUDtDxqKS5QXLH0EGA=="], + "fumadocs-ui": ["fumadocs-ui@16.9.3", "", { "dependencies": { "@fumadocs/tailwind": "0.0.5", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-direction": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.2.14", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-presence": "^1.1.5", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "class-variance-authority": "^0.7.1", "lucide-react": "^1.17.0", "motion": "^12.40.0", "next-themes": "^0.4.6", "react-remove-scroll": "^2.7.2", "rehype-raw": "^7.0.0", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^4.1.0", "tailwind-merge": "^3.6.0", "unist-util-visit": "^5.1.0" }, "peerDependencies": { "@takumi-rs/image-response": "*", "@types/mdx": "*", "@types/react": "*", "fumadocs-core": "16.9.3", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0" }, "optionalPeers": ["@takumi-rs/image-response", "@types/mdx", "@types/react", "next"] }, "sha512-eoVKj1H+ATut0su+WIoPWBLRqzPMGD0hekIBr4GopWvUg1lS997HL4kP+Leyf+3CYlZtFgyXb6ylbvRLFtEj6Q=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -1513,16 +1514,24 @@ "hasown": ["hasown@2.0.3", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg=="], + "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], + + "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], + + "hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="], + "hast-util-to-estree": ["hast-util-to-estree@3.1.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-attach-comments": "^3.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w=="], "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="], - "hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="], + "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="], "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + "hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="], + "hls.js": ["hls.js@1.6.16", "", {}, "sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA=="], "hono": ["hono@4.12.15", "", {}, "sha512-qM0jDhFEaCBb4TxoW7f53Qrpv9RBiayUHo0S52JudprkhvpjIrGoU1mnnr29Fvd1U335ZFPZQY1wlkqgfGXyLg=="], @@ -1543,8 +1552,6 @@ "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], - "image-size": ["image-size@2.0.2", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w=="], - "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], @@ -1749,7 +1756,7 @@ "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], - "lru-cache": ["lru-cache@11.3.5", "", {}, "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw=="], + "lru-cache": ["lru-cache@4.1.5", "", { "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="], "lucide-react": ["lucide-react@0.544.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-t5tS44bqd825zAW45UQxpG2CvcC4urOwn2TrwSH8u+MjeE+1NnWl6QqeQ/6NdjMqdOygyiT9p3Ev0p1NJykxjw=="], @@ -1929,7 +1936,7 @@ "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], - "next": ["next@15.5.4", "", { "dependencies": { "@next/env": "15.5.4", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.4", "@next/swc-darwin-x64": "15.5.4", "@next/swc-linux-arm64-gnu": "15.5.4", "@next/swc-linux-arm64-musl": "15.5.4", "@next/swc-linux-x64-gnu": "15.5.4", "@next/swc-linux-x64-musl": "15.5.4", "@next/swc-win32-arm64-msvc": "15.5.4", "@next/swc-win32-x64-msvc": "15.5.4", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-xH4Yjhb82sFYQfY3vbkJfgSDgXvBB6a8xPs9i35k6oZJRoQRihZH+4s9Yo2qsWpzBmZ3lPXaJ2KPXLfkvW4LnA=="], + "next": ["next@16.2.7", "", { "dependencies": { "@next/env": "16.2.7", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.2.7", "@next/swc-darwin-x64": "16.2.7", "@next/swc-linux-arm64-gnu": "16.2.7", "@next/swc-linux-arm64-musl": "16.2.7", "@next/swc-linux-x64-gnu": "16.2.7", "@next/swc-linux-x64-musl": "16.2.7", "@next/swc-win32-arm64-msvc": "16.2.7", "@next/swc-win32-x64-msvc": "16.2.7", "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-eMJxgjRzBaj3olkP4cBamHDXL79A8FC6u1GcsO1D1Tsx8bw/LLXUJCaoajVxtnhD3A1IJqIT8IcRJjgBIPJq4w=="], "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="], @@ -1949,8 +1956,6 @@ "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - "npm-to-yarn": ["npm-to-yarn@3.0.1", "", {}, "sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A=="], - "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], @@ -1997,6 +2002,8 @@ "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], + "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], @@ -2007,7 +2014,7 @@ "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], - "path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], + "path-to-regexp": ["path-to-regexp@0.1.13", "", {}, "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA=="], "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], @@ -2039,7 +2046,7 @@ "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="], - "postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], + "postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], @@ -2087,8 +2094,6 @@ "react-dom": ["react-dom@19.2.5", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.5" } }, "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag=="], - "react-medium-image-zoom": ["react-medium-image-zoom@5.4.3", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-cDIwdn35fRUPsGnnj/cG6Pacll+z+Mfv6EWU2wDO5ngbZjg5uLRb2ZhEnh92ufbXCJDFvXHekb8G3+oKqUcv5g=="], - "react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="], "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="], @@ -2113,7 +2118,7 @@ "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], "real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="], @@ -2141,6 +2146,8 @@ "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="], + "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], + "rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="], "remark": ["remark@15.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A=="], @@ -2229,7 +2236,7 @@ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - "shiki": ["shiki@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/engine-javascript": "3.23.0", "@shikijs/engine-oniguruma": "3.23.0", "@shikijs/langs": "3.23.0", "@shikijs/themes": "3.23.0", "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA=="], + "shiki": ["shiki@4.3.0", "", { "dependencies": { "@shikijs/core": "4.3.0", "@shikijs/engine-javascript": "4.3.0", "@shikijs/engine-oniguruma": "4.3.0", "@shikijs/langs": "4.3.0", "@shikijs/themes": "4.3.0", "@shikijs/types": "4.3.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-NKKjWzR6LIGL3sXBrWDw9sDS9cxx42/DkysaNqJEeOWE8Kix5gpak0bc00OfDVEO4oyXSyz8+aRaqKoBD1yo7A=="], "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], @@ -2427,6 +2434,8 @@ "unist-util-position-from-estree": ["unist-util-position-from-estree@2.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ=="], + "unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="], + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], @@ -2463,6 +2472,8 @@ "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + "vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="], + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], "vision-basic-example": ["vision-basic-example@workspace:examples/vision"], @@ -2473,6 +2484,8 @@ "web": ["web@workspace:apps/web"], + "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], + "webgl-constants": ["webgl-constants@1.1.1", "", {}, "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="], "webgl-sdf-generator": ["webgl-sdf-generator@1.1.1", "", {}, "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA=="], @@ -2639,6 +2652,10 @@ "docs/@types/node": ["@types/node@24.6.2", "", { "dependencies": { "undici-types": "~7.13.0" } }, "sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang=="], + "docs/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + + "drizzle-kit/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + "elysia/cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], "eslint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], @@ -2655,7 +2672,15 @@ "fastify-type-provider-zod/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "fumadocs-ui/tailwind-merge": ["tailwind-merge@3.5.0", "", {}, "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A=="], + "fumadocs-mdx/tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], + + "fumadocs-mdx/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + + "fumadocs-ui/lucide-react": ["lucide-react@1.22.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-c9o3l0PiNcgOQDW4F31BEYHudE7kgxVt3o30qMl36ZPwTxXlGB4QnLilhERvVM4uh/pl5MDyY1/gzZSYcHDtBg=="], + + "fumadocs-ui/motion": ["motion@12.42.2", "", { "dependencies": { "framer-motion": "^12.42.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Atvv11yUKIid41cVrRBDVX5m8tF8kNpExRSlbpt6APClhDjtwQssgFHhQzejxw7/7YYbjHSPKBVbHo05BuJT5Q=="], + + "fumadocs-ui/tailwind-merge": ["tailwind-merge@3.6.0", "", {}, "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w=="], "git-raw-commits/meow": ["meow@12.1.1", "", {}, "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw=="], @@ -2693,8 +2718,6 @@ "postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "postcss-nested/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], - "promise-worker-transferable/is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="], "raw-body/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], @@ -2713,6 +2736,8 @@ "read-yaml-file/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + "router/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], + "send/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], "smartwrap/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], @@ -2731,6 +2756,8 @@ "type-is/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + "vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + "web/lucide-react": ["lucide-react@0.468.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } }, "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA=="], "web/tailwindcss": ["tailwindcss@3.4.19", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ=="], @@ -2823,6 +2850,58 @@ "docs/@types/node/undici-types": ["undici-types@7.13.0", "", {}, "sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ=="], + "drizzle-kit/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + + "drizzle-kit/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + + "drizzle-kit/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + + "drizzle-kit/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + + "drizzle-kit/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + + "drizzle-kit/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + + "drizzle-kit/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + + "drizzle-kit/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + + "drizzle-kit/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + + "drizzle-kit/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + + "drizzle-kit/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + + "drizzle-kit/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + + "drizzle-kit/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + + "drizzle-kit/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + + "drizzle-kit/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + + "drizzle-kit/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + + "drizzle-kit/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + + "drizzle-kit/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + + "drizzle-kit/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + + "drizzle-kit/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + + "drizzle-kit/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + + "drizzle-kit/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + + "drizzle-kit/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + + "drizzle-kit/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + + "drizzle-kit/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + + "drizzle-kit/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "eslint/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "eslint/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], @@ -2843,8 +2922,6 @@ "express-basic-example/express/merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="], - "express-basic-example/express/path-to-regexp": ["path-to-regexp@0.1.13", "", {}, "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA=="], - "express-basic-example/express/qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], "express-basic-example/express/send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="], @@ -2857,6 +2934,8 @@ "fast-json-stringify/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "fumadocs-ui/motion/framer-motion": ["framer-motion@12.42.2", "", { "dependencies": { "motion-dom": "^12.42.2", "motion-utils": "^12.39.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5XY9luDiu0oHfHBjpDthFMh0ES+122w6p/papSJBweMkO8Sn+PW2QaEgRblQBpWFnuvZS5qvarpt/hO2pjGmnw=="], + "load-yaml-file/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], "next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], @@ -2895,8 +2974,6 @@ "smartwrap/yargs/y18n": ["y18n@4.0.3", "", {}, "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="], - "spawndamnit/cross-spawn/lru-cache": ["lru-cache@4.1.5", "", { "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="], - "spawndamnit/cross-spawn/shebang-command": ["shebang-command@1.2.0", "", { "dependencies": { "shebang-regex": "^1.0.0" } }, "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg=="], "spawndamnit/cross-spawn/which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "./bin/which" } }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="], @@ -2959,9 +3036,59 @@ "type-is/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], - "web/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + + "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + + "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + + "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + + "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + + "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + + "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + + "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + + "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], - "web/tailwindcss/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + + "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + + "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + + "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + + "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + + "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + + "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + + "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + + "vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + + "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + + "vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + + "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + + "vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + + "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + + "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + + "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + + "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + + "web/tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], "wrap-ansi/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], @@ -2981,6 +3108,10 @@ "express-basic-example/express/type-is/media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], + "fumadocs-ui/motion/framer-motion/motion-dom": ["motion-dom@12.42.2", "", { "dependencies": { "motion-utils": "^12.39.0" } }, "sha512-5gIMWLp/PycBtJRJWRgjxke5n8dlvkSn2DrYW+tr3XcqAZY1xZh6BJyooJXCM8wdfM7wfMjkBJNLge1CKPUIRA=="], + + "fumadocs-ui/motion/framer-motion/motion-utils": ["motion-utils@12.39.0", "", {}, "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ=="], + "nextjs-vision-example/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "pkg-dir/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], diff --git a/packages/server/README.md b/packages/server/README.md index 2456290..fbf8e94 100644 --- a/packages/server/README.md +++ b/packages/server/README.md @@ -6,9 +6,9 @@ Built on Elysia. Automatic tracing. Type-safe APIs. Pub/Sub & Cron. Zero config. ## Why Vision Server? -**vs NestJS:** Faster, simpler, better DX -**vs Encore.ts:** Open source, no vendor lock-in -**vs Plain Elysia:** Built-in observability, type-safety, pub/sub & cron +**vs NestJS:** Orders of magnitude faster, zero DI ceremony, built-in observability +**vs Encore.ts:** 100% open source (MIT), no vendor lock-in +**vs Plain Elysia:** Built-in observability, pub/sub & cron, rate limiting, module pattern ## Quick Start @@ -49,205 +49,226 @@ const usersModule = createModule({ prefix: '/users' }) const app = createVision({ service: { name: 'My API', version: '1.0.0' }, - vision: { enabled: true }, pubsub: { devMode: true }, -}) - .use(usersModule) - .listen(3000) +}).use(usersModule) + +app.listen(3000) + +/** Eden Treaty client type — export for the frontend. */ +export type AppType = typeof app ``` **That's it!** You get: + - ✅ Vision Dashboard on port 9500 - ✅ Automatic request tracing -- ✅ Type-safe validation -- ✅ Pub/Sub events (BullMQ-based) -- ✅ Eden Treaty client support (`treaty`) +- ✅ Type-safe validation (Zod / Valibot / TypeBox via Standard Schema) +- ✅ Pub/Sub events (BullMQ-based, in-memory in dev) +- ✅ Eden Treaty client support — `treaty` + +## The Module Pattern + +Vision composes apps from small, focused **modules**. A module is an Elysia plugin with Vision's per-request context (`span`, `emit`, `addContext`, `traceId`) already typed in. + +```typescript +const ordersModule = createModule({ prefix: '/orders' }) + .use(defineEvents({ 'order/placed': { schema, handler } })) + .post( + '/', + async ({ body, emit }) => { + await emit('order/placed', { orderId: '...', total: body.total }) + return { ok: true } + }, + { body: OrderBody } + ) +``` + +Compose at the root via `.use()` — order doesn't matter, and each module contributes its own routes, events, and crons: + +```typescript +const app = createVision({ service: { name: 'Shop' } }) + .use(usersModule) + .use(ordersModule) + .use(productsModule) +``` ## Features -### 🚀 Zero Configuration +### 🚀 Zero configuration Everything works out of the box: -- Vision Dashboard automatically starts -- Tracing middleware auto-installed -- Event bus auto-initialized (BullMQ) -- Service catalog auto-discovered -### 🔥 c.span() Built Into Context +- Vision Dashboard starts automatically on port 9500 +- Tracing hooks are pre-wired (`onRequest`, `onAfterResponse`, `onError`) +- Service & route catalog auto-registered (once on `listen`, or lazily on first request for `.handle(req)` deployments like Next.js) +- BullMQ event bus auto-initialized (in-memory in `devMode`, Redis in production) -No more `useVisionSpan()` or manual imports: +### 🔥 `span` / `emit` / `addContext` / `traceId` in every handler + +Every HTTP handler receives Vision's context alongside Elysia's `body/query/params`: ```typescript -async (data, c) => { - // Just use c.span()! - const user = c.span('db.select', { 'db.table': 'users' }, () => { - return db.users.findOne(data.id) - }) - - const posts = c.span('db.select', { 'db.table': 'posts' }, () => { - return db.posts.findMany({ userId: user.id }) +.post('/', async ({ body, span, emit, addContext, traceId }) => { + addContext({ 'user.email': body.email }) + + const user = span('db.insert', { 'db.table': 'users' }, () => { + return db.users.create(body) }) - - return { user, posts } -} + + await emit('user/created', { userId: user.id, email: user.email }) + return { ...user, traceId } +}) ``` -### ✅ Type-Safe Everything +### ✅ Validation with any Standard Schema library -Zod validation for inputs and outputs: +Use Zod, Valibot, or Elysia's built-in TypeBox (`t`) — all interchangeable, mix per route: ```typescript -app.endpoint('POST', '/users', { - input: z.object({ - name: z.string().min(1), - email: z.string().email() - }), - output: z.object({ - id: z.string() - }) -}, async (data, c) => { - // data is fully typed! - return { id: '123' } -}) +import { t } from '@getvision/server' +import { z } from 'zod' +import * as v from 'valibot' + +.post('/', handler, { body: z.object({ name: z.string() }) }) // Zod +.post('/', handler, { body: v.object({ name: v.string() }) }) // Valibot +.post('/', handler, { body: t.Object({ name: t.String() }) }) // TypeBox ``` -### 📡 Pub/Sub & Cron Built-In +Invalid request → Elysia returns a `422` with validation details automatically. -BullMQ event bus is built-in: +### 📡 Built-in pub/sub & cron + +Powered by BullMQ — in-memory during development, Redis-backed in production: ```typescript -// Subscribe to events -app.on('user/created', async (event) => { - await sendWelcomeEmail(event.data.email) -}) - // Schedule cron jobs -.cron('0 0 * * *', async () => { - await cleanupInactiveUsers() -}) +import { createModule, defineEvents, defineCrons } from '@getvision/server' + +const notificationsModule = createModule() + .use( + defineEvents({ + 'user/created': { + schema: z.object({ userId: z.string(), email: z.string() }), + description: 'User account created', + icon: '👤', + tags: ['user', 'auth'], + handler: async (event) => { + await sendWelcomeEmail(event.email) + }, + }, + }) + ) + .use( + defineCrons({ + 'nightly-cleanup': { + schedule: '0 0 * * *', + handler: async () => { + await db.sessions.deleteExpired() + }, + }, + }) + ) +``` + +Emit events from any handler using the context: -// Send events from handlers -await c.emit('user/created', { userId: '123', email: 'user@example.com' }) +```typescript +await emit('user/created', { userId: '123', email: 'user@example.com' }) ``` -### 🎯 Service Builder Pattern +Trace context (`traceId`/`spanId`) is propagated through the BullMQ job envelope, so event/cron handlers join the same trace as the request that emitted them. + +### 🎯 Elysia-native -Organize your code by services: +The underlying instance is Elysia — every plugin and feature works unmodified: ```typescript -app.service('users') - .on('user/created', handler) - .endpoint('GET', '/users', schema, handler) - .endpoint('POST', '/users', schema, handler) - .cron('0 0 * * *', handler) - -app.service('orders') - .on('order/placed', handler) - .endpoint('GET', '/orders', schema, handler) - .endpoint('POST', '/orders', schema, handler) +import { cors } from '@elysia/cors' +import { swagger } from '@elysiajs/swagger' + +const app = createVision({ service: { name: 'My API' } }) + .use(cors()) + .use(swagger()) + .use(usersModule) + .get('/health', () => ({ status: 'ok' })) ``` -> Note: Declare `service.on('event', { schema, handler })` BEFORE any endpoint that calls `c.emit('event', ...)`. -> This ensures TypeScript can infer the event type for `c.emit`, otherwise you'll get type errors. +### 🔒 Per-endpoint rate limiting -### 🔐 Middleware Support +```typescript +import { rateLimit } from '@getvision/server' -Add middleware globally or per-service: +.post('/', handler, { + body: SignupBody, + beforeHandle: [rateLimit({ requests: 5, window: '15m' })], +}) +``` + +Module-level — apply once to every route in the module: ```typescript -import { logger } from 'hono/logger' -import { jwt } from 'hono/jwt' - -// Global middleware -app.use('*', logger()) - -// Service-level middleware (applies to all endpoints) -app.service('admin') - .use(jwt({ secret: 'secret' })) // Protect all admin endpoints - .endpoint('GET', '/admin/users', schema, handler) - .endpoint('POST', '/admin/settings', schema, handler) - -// Endpoint-level middleware -app.service('users') - .endpoint('GET', '/users', schema, handler) // Public - .endpoint('POST', '/users', schema, handler, { - middleware: [authMiddleware] // Protected - }) +const adminModule = createModule({ prefix: '/admin' }) + .onBeforeHandle(rateLimit({ requests: 10, window: '30s' })) + .get('/stats', handler) + .delete('/sessions/:id', handler) ``` -### 🔮 Vision Dashboard Included +### 🧩 Eden Treaty — typed RPC on the client -Automatic observability: -- 📊 Real-time request tracing -- 📝 Live logs -- 🏗️ Service catalog -- 🔍 Waterfall visualization -- 📈 Performance metrics +```typescript +import { treaty } from '@elysia/eden' +import type { AppType } from './server' -Visit `http://localhost:9500` after starting your app! +const api = treaty('http://localhost:3000') -## API Reference +const { data } = await api.users.get() +// ^? { users: { id: string; name: string }[] } +``` + +Change a schema on the server → the client gets a compile error. No codegen. + +### 🔮 Vision Dashboard + +Visit `http://localhost:9500` after starting your app: -### `new Vision(config)` +- 📊 Real-time request tracing with waterfall visualization +- 📝 Live logs (linked to the trace that emitted them) +- 🏗️ Service, route, event and cron catalog +- 🧪 API Explorer — auto-generated request templates from your schemas +- 📈 Performance metrics -Create a new Vision app. +## Configuration ```typescript -const app = new Vision({ +const app = createVision({ service: { name: 'My API', version: '1.0.0', description: 'Optional description', integrations: { - database: 'postgresql://localhost/mydb', // Optional - redis: 'redis://localhost:6379' // Optional + database: 'postgresql://localhost/mydb', + redis: 'redis://localhost:6379', }, drizzle: { - autoStart: true, // Auto-start Drizzle Studio - port: 4983 // Drizzle Studio port - } + autoStart: true, // auto-start Drizzle Studio in dev + port: 4983, + }, }, vision: { - enabled: true, // Enable/disable dashboard - port: 9500, // Dashboard port - maxTraces: 1000, // Max traces to store - maxLogs: 10000, // Max logs to store - logging: true, // Console logging - // exporters: [...] // Forward traces to OTLP backends — see "OTLP Trace Export" + enabled: true, // enable/disable dashboard + port: 9500, // dashboard port + maxTraces: 1000, + maxLogs: 10000, + logging: true, + // exporters: [...] // forward traces to OTLP backends — see below }, pubsub: { - devMode: true, // In-memory BullMQ for local dev - redis: { - host: 'localhost', - port: 6379, - password: 'your-password', - // Connection settings to prevent timeouts - keepAlive: 30000, // Keep connection alive (30s) - maxRetriesPerRequest: null, // Required null for BullMQ - enableReadyCheck: true, // Check Redis is ready - connectTimeout: 10000, // Connection timeout (10s) - enableOfflineQueue: true // Queue commands when offline - }, - // BullMQ options - queue: { - defaultJobOptions: { - lockDuration: 300000, // 5 minutes - stalledInterval: 300000, - maxStalledCount: 1, - removeOnComplete: 1000, - removeOnFail: 1000, - } - }, - worker: { - lockDuration: 300000, - }, - queueEvents: { - stalledInterval: 300000, - } - } + devMode: true, // in-memory queue — no Redis required + // redis: { host: 'localhost', port: 6379 } + }, }) ``` -### OTLP Trace Export +## OTLP Trace Export Forward every completed trace to any OpenTelemetry-compatible backend — BetterStack, Honeycomb, Grafana Tempo, Datadog, an OTel Collector, and so on — by adding an `OtlpTraceExporter` to `vision.exporters`. Export runs alongside the local Dashboard, so traces show up in both. @@ -270,7 +291,7 @@ createVision({ The exporter speaks OTLP/JSON over HTTP — the destination is purely a matter of `endpoint` + `headers`, so the same code targets any OTLP backend (switching from BetterStack to Honeycomb is a URL + header change, not a code change). Traces are buffered and flushed in batches; failed batches are re-buffered for the next flush so a transient backend outage doesn't silently lose traces, and a failing exporter is isolated so it never affects request handling. -Vision models each HTTP request as a synthetic root span (`SERVER`) with your `c.span(...)` calls as nested `INTERNAL` spans, and attaches the trace's logs as span events. +Vision models each HTTP request as a synthetic root span (`SERVER`) with your `span(...)` calls as nested `INTERNAL` spans, and attaches the trace's logs as span events. **`OtlpTraceExporter` options** @@ -288,347 +309,308 @@ Vision models each HTTP request as a synthetic root span (`SERVER`) with your `c > Need a custom sink (custom format, webhook, second dashboard)? Implement the `TraceExporter` interface (`export(trace)` + optional `shutdown()`) and add it to `vision.exporters` — `OtlpTraceExporter` is just the built-in one. -### `app.service(name)` +## API Reference + +### `createVision(config)` -Create a new service builder. +Create a new Vision app. Returns an Elysia instance decorated with Vision's per-request context. ```typescript -app.service('users') - .on(...) - .endpoint(...) - .cron(...) +const app = createVision({ + service: { name: 'My API', version: '1.0.0' }, + pubsub: { devMode: true }, +}) ``` -### `service.endpoint(method, path, schema, handler, config?)` +See [Configuration](#configuration) for all options. + +### `createModule({ prefix? })` -Define a type-safe HTTP endpoint. +Create a new module. Equivalent to `new Elysia({ prefix })` with Vision's context types pre-decorated. ```typescript -.endpoint( - 'GET', - '/users/:id', - { - input: z.object({ id: z.string() }), - output: z.object({ id: z.string(), name: z.string() }) - }, - async ({ id }, c) => { - // handler with c.span() available - return { id, name: 'John' } - }, - { - middleware: [authMiddleware] // Optional - } -) +const usersModule = createModule({ prefix: '/users' }) + .get('/', handler) + .post('/', handler, { body: schema }) ``` -### `service.on(eventName, handler)` +### `defineEvents(map)` -Subscribe to events. +Register pub/sub event schemas and handlers. Returns an Elysia plugin — `.use()` it inside the module that owns the events. ```typescript -.on('user/created', async (event) => { - console.log(event.data) -}) +createModule().use( + defineEvents({ + 'user/created': { + schema: z.object({ userId: z.string(), email: z.string().email() }), + description: 'User account created', + icon: '👤', + tags: ['user', 'auth'], + handler: async (event) => { + await sendWelcomeEmail(event.email) + }, + }, + }) +) ``` -### `service.cron(schedule, handler, options?)` +### `defineCrons(map)` -Schedule a cron job. +Register cron jobs. Returns an Elysia plugin. ```typescript -.cron('0 0 * * *', async () => { - console.log('Daily job') -}, { id: 'custom-id' }) +createModule().use( + defineCrons({ + 'nightly-cleanup': { + schedule: '0 0 * * *', + description: 'Purge expired sessions', + handler: async () => { + await db.sessions.deleteExpired() + }, + }, + }) +) ``` -### `c.span(name, attributes, fn)` +Crons run under BullMQ's repeatable jobs — in-memory in `devMode`, Redis-backed in production. + +### `rateLimit(options)` -Create a custom span (built into context). +Token-bucket rate limiter. Plugs into Elysia's `beforeHandle` hook on a route or module. ```typescript -const result = c.span('operation.name', { - 'attribute.key': 'value' -}, () => { - // Your code here - return someResult +rateLimit({ + requests: 100, + window: '1h', + keyBy: ({ request }) => request.headers.get('x-user-id') ?? 'anonymous', }) ``` -### Event emission +- **`requests`** — max requests per window +- **`window`** — `'30s'`, `'15m'`, `'1h'`, `'2d'`, or ms as a string +- **`keyBy`** — optional key function (defaults to client IP, falls back to `User-Agent`) +- **`store`** — optional `RateLimitStore` (defaults to in-memory `MemoryRateLimitStore`) + +Exceeding the limit returns `429 Too Many Requests` with `RateLimit-*` / `Retry-After` headers. -Emit events from handlers using the context: +### Handler context + +Every handler receives a merged Elysia + Vision context: ```typescript -await c.emit('user/created', { userId: '123', email: 'user@example.com' }) +.post('/', async ({ body, params, query, set, // Elysia + span, emit, addContext, traceId }) => // Vision +{ /* ... */ }) ``` -### `app.getVision()` +- **`span(name, attributes, fn)`** — wraps a block in a tracing span; returns `fn()`'s result. Detects async callbacks and defers `endSpan()` until the promise settles. +- **`emit(event, payload)`** — publishes a typed event; payload is validated against the schema from `defineEvents`. +- **`addContext(attrs)`** — adds "wide event" attributes to the current trace; subsequent logs pick them up automatically. +- **`traceId`** — current request's trace id (for error response correlation, structured logging). -Get the VisionCore instance. +### `ready(app)` / `close(app)` ```typescript -const vision = app.getVision() -const tracer = vision.getTracer() +import { ready, close } from '@getvision/server' + +await ready(app) // waits for dashboard, event bus, and Drizzle Studio to be up +// ... work ... +await close(app) // graceful shutdown — drains BullMQ workers, stops dashboard, terminates Drizzle Studio ``` -### `app.start(port, options?)` +Idempotent. `close()` is also auto-registered with `import.meta.hot?.dispose` when you use `.listen()` with `bun --hot`. Available as both top-level functions and instance methods (`app.close()`). + +### `getVisionContext()` -Start the server (convenience method). +Access the current request's Vision context from anywhere (utilities, libs called deep in the call stack). Backed by AsyncLocalStorage: ```typescript -await app.start(3000) -// or -await app.start(3000, { hostname: '0.0.0.0' }) +import { getVisionContext } from '@getvision/server' + +function logSomething() { + const ctx = getVisionContext() + ctx?.addContext({ 'lib.called': true }) +} ``` -## Drizzle Integration +### `t` (TypeBox) -Vision Server automatically detects and integrates with Drizzle ORM. +Re-export of Elysia's `t` for users who prefer TypeBox over Zod/Valibot: -### Auto-Start Drizzle Studio +```typescript +import { t } from '@getvision/server' + +.post('/', handler, { body: t.Object({ name: t.String() }) }) +``` + +### `EventBus` (advanced) + +The internal pub/sub class — exposed for sharing a bus across multiple apps or for manual wiring. Most users never need this. + +## Drizzle Integration + +Vision auto-detects Drizzle ORM and starts Drizzle Studio in development. ```typescript -const app = new Vision({ +const app = createVision({ service: { name: 'My API', - integrations: { - database: 'sqlite://./dev.db' - }, + integrations: { database: 'sqlite://./dev.db' }, drizzle: { - autoStart: true, // Start Drizzle Studio automatically - port: 4983 // Default: 4983 - } - } + autoStart: true, // auto-start Drizzle Studio + port: 4983, // default port + }, + }, }) ``` **What happens:** + 1. ✅ Detects `drizzle.config.ts` in your project -2. ✅ Auto-starts Drizzle Studio on port 4983 -3. ✅ Displays in Vision Dashboard → Integrations +2. ✅ Starts Drizzle Studio on port 4983 +3. ✅ Surfaces it in the Vision Dashboard → Integrations 4. ✅ Links to https://local.drizzle.studio -### Use with c.span() +Trace database calls with `span`: ```typescript -app.service('users') - .endpoint('GET', '/users/:id', schema, async ({ id }, c) => { - // Trace database queries - const user = c.span('db.select', { - 'db.system': 'sqlite', - 'db.table': 'users' - }, () => { - return db.select().from(users).where(eq(users.id, id)).get() - }) - - return user +.get('/users/:id', ({ params, span }) => { + return span('db.select', { 'db.system': 'sqlite', 'db.table': 'users' }, () => { + return db.select().from(users).where(eq(users.id, params.id)).get() }) +}, { params: z.object({ id: z.string() }) }) ``` -## Redis Connection Configuration - -### Preventing Connection Drops +## Redis Configuration -Redis connections can close due to timeouts or network issues, causing workers to fail with "Connection is closed" errors. Vision Server includes sensible defaults to help prevent this: +`devMode: true` uses an in-memory BullMQ — no Redis required. For production, point `pubsub.redis` at your Redis instance: ```typescript -const app = new Vision({ +const app = createVision({ service: { name: 'My API' }, pubsub: { - devMode: false, // Use Redis in production + devMode: false, redis: { host: process.env.REDIS_HOST, port: parseInt(process.env.REDIS_PORT || '6379'), password: process.env.REDIS_PASSWORD, - // Connection settings (these are the defaults) - keepAlive: 30000, // Keep connection alive (30s) - maxRetriesPerRequest: null, // Required null for BullMQ - enableReadyCheck: true, // Check Redis is ready before commands - connectTimeout: 10000, // Connection timeout (10s) - enableOfflineQueue: true // Queue commands when offline - } - } + // Sensible defaults (these are the built-ins) + keepAlive: 30000, // prevent idle timeouts + maxRetriesPerRequest: null, // required null for BullMQ + enableReadyCheck: true, + connectTimeout: 10000, + enableOfflineQueue: true, + }, + }, }) ``` -**What this helps with:** -- ✅ **keepAlive (30s)**: Helps prevent idle connection timeouts -- ✅ **Automatic reconnection**: Retries up to 10 times with exponential backoff -- ✅ **Connection settings**: Each Queue/Worker/QueueEvents uses these connection settings -- ✅ **Offline queue**: Commands are queued when Redis is temporarily unavailable - -### Environment Variables - -You can also configure Redis via environment variables: +**Troubleshooting:** -```bash -# Option 1: Redis URL (recommended) -REDIS_URL=redis://:password@hostname:6379 - -# Option 2: Individual variables -REDIS_HOST=hostname -REDIS_PORT=6379 -REDIS_PASSWORD=password -``` - -### Troubleshooting - -**"Connection is closed" errors:** -- Vision Server now includes automatic reconnection with exponential backoff -- Check logs for `🔄 Redis reconnecting...` messages -- If reconnection fails after 10 attempts, check your Redis server health - -**"Could not renew lock for job" errors:** -- This happens when workers lose connection during job processing -- The new keepAlive setting (30s) prevents this -- Increase `keepAlive` if you have very long-running jobs - -**Custom retry strategy:** -```typescript -pubsub: { - redis: { - // ... other settings - keepAlive: 60000, // 60s for long-running jobs - maxRetriesPerRequest: 30 // More retries for unstable networks - } -} -``` - -## Hono Compatibility - -Vision extends Hono, so all Hono features work: - -```typescript -// Use any Hono middleware -app.use('*', logger()) -app.use('*', cors()) -app.use('/admin/*', jwt({ secret: 'secret' })) - -// Define routes Hono-style -app.get('/health', (c) => c.json({ status: 'ok' })) - -// Use Hono routing features -app.route('/api/v1', apiRoutes) - -// Access Hono methods -app.notFound((c) => c.json({ error: 'Not found' }, 404)) -app.onError((err, c) => c.json({ error: err.message }, 500)) -``` +- **"Connection is closed"** — Vision auto-reconnects with exponential backoff. Check logs for `🔄 Redis reconnecting...`. +- **"Could not renew lock for job"** — long-running jobs need a longer `keepAlive`. Bump it to `60000` (60s) or more. ## Complete Example -Here's a full working example with multiple services, pub/sub, and Drizzle: - ```typescript -import { Vision } from '@getvision/server' +import { + createVision, + createModule, + defineEvents, + defineCrons, + rateLimit, +} from '@getvision/server' import { z } from 'zod' import { db } from './db' import { users, orders } from './db/schema' import { eq } from 'drizzle-orm' -const app = new Vision({ - service: { - name: 'E-Commerce API', - version: '1.0.0', - integrations: { - database: 'sqlite://./dev.db' - }, - drizzle: { - autoStart: true, - port: 4983 - } - }, - vision: { - enabled: true, - port: 9500 - }, - pubsub: { - schemas: { +const User = z.object({ id: z.string(), name: z.string(), email: z.string().email() }) + +// — Users module ——————————————————————————— +const usersModule = createModule({ prefix: '/users' }) + .use( + defineEvents({ 'user/created': { - data: z.object({ - userId: z.string(), - email: z.string().email() - }) + schema: z.object({ userId: z.string(), email: z.string().email() }), + handler: async (event) => { + console.log('[welcome email] →', event.email) + }, }, - 'order/placed': { - data: z.object({ - orderId: z.string(), - userId: z.string(), - total: z.number() - }) - } - } - } -}) - -// User Service -app.service('users') - .endpoint('GET', '/users', { - input: z.object({}), - output: z.object({ - users: z.array(z.object({ - id: z.string(), - name: z.string() - })) - }) - }, async (_, c) => { - const allUsers = c.span('db.select', { 'db.table': 'users' }, () => { - return db.select().from(users).all() }) + ) + .get('/', ({ span }) => { + const allUsers = span('db.select', { 'db.table': 'users' }, () => + db.select().from(users).all() + ) return { users: allUsers } }) - .on('user/created', async (event) => { - console.log('Sending welcome email to:', event.data.email) - }) - .endpoint('POST', '/users', { - input: z.object({ - name: z.string().min(1), - email: z.string().email() - }), - output: z.object({ id: z.string() }) - }, async (data, c) => { - const user = c.span('db.insert', { 'db.table': 'users' }, () => { - return db.insert(users).values(data).returning().get() - }) - - // Emit event (type-safe) - await c.emit('user/created', { userId: user.id, email: user.email }) - - return { id: user.id } - }) + .post( + '/', + async ({ body, emit, span }) => { + const user = span('db.insert', { 'db.table': 'users' }, () => + db.insert(users).values(body).returning().get() + ) + await emit('user/created', { userId: user.id, email: user.email }) + return user + }, + { + body: z.object({ name: z.string().min(1), email: z.string().email() }), + response: User, + beforeHandle: [rateLimit({ requests: 5, window: '15m' })], + } + ) -// Order Service -app.service('orders') - .endpoint('POST', '/orders', { - input: z.object({ - userId: z.string(), - items: z.array(z.object({ - productId: z.string(), - quantity: z.number() - })) - }), - output: z.object({ orderId: z.string() }) - }, async (data, c) => { - const order = c.span('db.insert', { 'db.table': 'orders' }, () => { - return db.insert(orders).values({ - userId: data.userId, - total: 100 - }).returning().get() +// — Orders module —————————————————————————— +const ordersModule = createModule({ prefix: '/orders' }) + .use( + defineCrons({ + 'daily-summary': { + schedule: '0 0 * * *', + handler: async () => console.log('Daily order summary'), + }, }) - - return { orderId: order.id } - }) - .cron('0 0 * * *', async () => { - console.log('Daily order summary') - }) + ) + .post( + '/', + async ({ body, span }) => { + const order = span('db.insert', { 'db.table': 'orders' }, () => + db.insert(orders).values({ userId: body.userId, total: 100 }).returning().get() + ) + return { orderId: order.id } + }, + { + body: z.object({ + userId: z.string(), + items: z.array(z.object({ productId: z.string(), quantity: z.number() })), + }), + } + ) -app.start(3000) +// — Root app ——————————————————————————————— +const app = createVision({ + service: { + name: 'E-Commerce API', + version: '1.0.0', + integrations: { database: 'sqlite://./dev.db' }, + drizzle: { autoStart: true, port: 4983 }, + }, + vision: { enabled: true, port: 9500 }, + pubsub: { devMode: true }, +}) + .use(usersModule) + .use(ordersModule) + +app.listen(3000) + +/** Eden Treaty client type — export for the frontend. */ +export type AppType = typeof app ``` -### Run the Example +### Run it ```bash -# From project root +# From repo root bun run example:server # Or directly @@ -637,48 +619,55 @@ bun run dev ``` Visit: + - **API:** http://localhost:3000 - **Vision Dashboard:** http://localhost:9500 - **Drizzle Studio:** https://local.drizzle.studio +## Migrating from the Hono-era API + +The pre-1.0 `Vision` class, `app.service(...).endpoint(...)` builder, and file-based autodiscovery have all been replaced by the Elysia module pattern. See the [migration guide](https://getvision.dev/docs/server/migration) for a complete old → new mapping. + ## Why Vision Server? ### ✅ Advantages -**vs NestJS:** -- 10x faster (Hono vs Express) -- 10x simpler (no DI, no decorators) +**vs NestJS** +- Orders of magnitude faster (Bun + Elysia) +- 10× simpler — no DI, no decorators, no module graph - Built-in observability -**vs Encore.ts:** +**vs Encore.ts** - 100% open source (MIT) - No vendor lock-in -- Deploy anywhere +- Deploy anywhere (Bun, Node, Docker, edge) -**vs Plain Hono:** -- Built-in observability -- Type-safe validation -- Pub/Sub & Cron included -- Better code organization +**vs plain Elysia** +- Built-in tracing, logs, API Explorer +- Type-safe pub/sub & cron +- Per-endpoint rate limiting +- Module pattern for code organization ### 🎯 Perfect For - Greenfield projects - API-first architectures - Teams that want great DX -- Projects that need observability -- Anyone who wants NestJS features without the complexity +- Projects that need observability from day one +- Anyone who wants NestJS-style structure without the complexity ## Roadmap - [x] Drizzle integration with auto-start Studio -- [x] Type-safe validation with Zod -- [x] Auto-generated API schemas -- [ ] Cache layer (Redis integration) -- [ ] Rate limiting (per-endpoint & global) -- [ ] Testing helpers +- [x] Standard Schema validation (Zod / Valibot / TypeBox) +- [x] Pub/sub & cron via BullMQ +- [x] Per-endpoint rate limiting +- [x] OTLP trace export +- [x] Trace context propagation through pub/sub - [ ] OpenAPI generation - [ ] WebSocket support +- [ ] Cache layer (Redis-backed) +- [ ] Testing helpers ## License From 8554851ec2a9909f0e23f9df1452fd5084e407d6 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 06:30:58 +0000 Subject: [PATCH 07/11] fix(docs): cast getMDXComponents return for fumadocs 16 types The fumadocs 16 default MDX components no longer structurally match mdx/types' MDXComponents, which broke `next build` type-checking. Cast the merged map back to MDXComponents. --- apps/docs/mdx-components.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/docs/mdx-components.tsx b/apps/docs/mdx-components.tsx index d3fbb13..4738396 100644 --- a/apps/docs/mdx-components.tsx +++ b/apps/docs/mdx-components.tsx @@ -1,10 +1,10 @@ -import defaultMdxComponents from 'fumadocs-ui/mdx'; -import type { MDXComponents } from 'mdx/types'; +import defaultMdxComponents from "fumadocs-ui/mdx"; +import type { MDXComponents } from "mdx/types"; // use this function to get MDX components, you will need it for rendering MDX export function getMDXComponents(components?: MDXComponents): MDXComponents { return { ...defaultMdxComponents, ...components, - }; + } as MDXComponents; } From b265e0cb82e3c499eadd469ec65e9ded206718fd Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 06:30:58 +0000 Subject: [PATCH 08/11] feat(docs): lead with the auto-generated dashboard, drop competitor names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Hero and a new lead feature card now headline the auto-generated dashboard (route/service discovery, zero config) — the core feature - Remove Encore.ts by name from the landing (comparison link and card reworded generically); the docs still carry the full comparison - Crossfade the WebGL beams in over the static background so the hero no longer visibly pops from fallback to animation --- apps/docs/app/(home)/_components/beams-bg.tsx | 17 ++++++++++++++++- apps/docs/app/(home)/_components/below.tsx | 16 ++++++++-------- apps/docs/app/(home)/_components/hero.tsx | 6 +++--- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/apps/docs/app/(home)/_components/beams-bg.tsx b/apps/docs/app/(home)/_components/beams-bg.tsx index c5e261a..ea7f231 100644 --- a/apps/docs/app/(home)/_components/beams-bg.tsx +++ b/apps/docs/app/(home)/_components/beams-bg.tsx @@ -12,6 +12,7 @@ const Beams = dynamic(() => import("./beams/Beams"), { ssr: false }); */ export function BeamsBg() { const [show, setShow] = useState(false); + const [ready, setReady] = useState(false); useEffect(() => { const motionOk = window.matchMedia("(prefers-reduced-motion: reduce)"); @@ -21,10 +22,24 @@ export function BeamsBg() { return () => motionOk.removeEventListener("change", update); }, []); + useEffect(() => { + if (!show) { + setReady(false); + return; + } + // let the WebGL canvas paint before we fade it in over the static bg + const t = setTimeout(() => setReady(true), 350); + return () => clearTimeout(t); + }, [show]); + if (!show) return null; return ( -
    +
    - See the full comparison with Encore.ts + See how Vision compares diff --git a/apps/docs/app/(home)/_components/hero.tsx b/apps/docs/app/(home)/_components/hero.tsx index f5be1bd..2791ac3 100644 --- a/apps/docs/app/(home)/_components/hero.tsx +++ b/apps/docs/app/(home)/_components/hero.tsx @@ -43,9 +43,9 @@ export function Hero() {

    - Add live traces, logs, and an API playground to the Express, Fastify, - Hono or Elysia app you already have. Two lines of code — no rewrite, - no vendor lock-in. + Vision auto-generates a full dashboard for the Express, Fastify, Hono + or Elysia app you already have — routes, traces, logs and an API + playground. Two lines of code, zero config.

    From b2c8299ca14a5bc9f609b40b20dc152cc047b32f Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 06:42:31 +0000 Subject: [PATCH 09/11] refactor(docs): drop the hero grid, keep the opaque beams background The transparent-canvas + grid combination muddied the beams; revert to the opaque beams look and remove the now-unused grid layer and its CSS. --- .../app/(home)/_components/beams/Beams.tsx | 60 +++++++++---------- apps/docs/app/(home)/_components/hero.tsx | 1 - apps/docs/app/global.css | 14 ----- 3 files changed, 30 insertions(+), 45 deletions(-) diff --git a/apps/docs/app/(home)/_components/beams/Beams.tsx b/apps/docs/app/(home)/_components/beams/Beams.tsx index fa2cf61..67484d2 100644 --- a/apps/docs/app/(home)/_components/beams/Beams.tsx +++ b/apps/docs/app/(home)/_components/beams/Beams.tsx @@ -1,7 +1,7 @@ // @ts-nocheck /* eslint-disable react/no-unknown-property */ // Beams background — adapted from React Bits (https://reactbits.dev), MIT. -'use client'; +"use client"; import { forwardRef, @@ -9,15 +9,15 @@ import { useEffect, useRef, useMemo, -} from 'react'; +} from "react"; -import * as THREE from 'three'; +import * as THREE from "three"; -import { Canvas, useFrame } from '@react-three/fiber'; -import { PerspectiveCamera } from '@react-three/drei'; -import { degToRad } from 'three/src/math/MathUtils.js'; +import { Canvas, useFrame } from "@react-three/fiber"; +import { PerspectiveCamera } from "@react-three/drei"; +import { degToRad } from "three/src/math/MathUtils.js"; -import './Beams.css'; +import "./Beams.css"; function extendMaterial(BaseMaterial, cfg) { const physical = THREE.ShaderLib.physical; @@ -33,19 +33,19 @@ function extendMaterial(BaseMaterial, cfg) { const defaults = new BaseMaterial(cfg.material || {}); if (defaults.color) uniforms.diffuse.value = defaults.color; - if ('roughness' in defaults) uniforms.roughness.value = defaults.roughness; - if ('metalness' in defaults) uniforms.metalness.value = defaults.metalness; - if ('envMap' in defaults) uniforms.envMap.value = defaults.envMap; - if ('envMapIntensity' in defaults) + if ("roughness" in defaults) uniforms.roughness.value = defaults.roughness; + if ("metalness" in defaults) uniforms.metalness.value = defaults.metalness; + if ("envMap" in defaults) uniforms.envMap.value = defaults.envMap; + if ("envMapIntensity" in defaults) uniforms.envMapIntensity.value = defaults.envMapIntensity; Object.entries(cfg.uniforms ?? {}).forEach(([key, u]) => { uniforms[key] = - u !== null && typeof u === 'object' && 'value' in u ? u : { value: u }; + u !== null && typeof u === "object" && "value" in u ? u : { value: u }; }); - let vert = `${cfg.header}\n${cfg.vertexHeader ?? ''}\n${baseVert}`; - let frag = `${cfg.header}\n${cfg.fragmentHeader ?? ''}\n${baseFrag}`; + let vert = `${cfg.header}\n${cfg.vertexHeader ?? ""}\n${baseVert}`; + let frag = `${cfg.header}\n${cfg.fragmentHeader ?? ""}\n${baseFrag}`; for (const [inc, code] of Object.entries(cfg.vertex ?? {})) { vert = vert.replace(inc, `${inc}\n${code}`); @@ -73,7 +73,7 @@ const CanvasWrapper = ({ children }) => ( ); const hexToNormalizedRGB = (hex) => { - const clean = hex.replace('#', ''); + const clean = hex.replace("#", ""); const r = parseInt(clean.substring(0, 2), 16); const g = parseInt(clean.substring(2, 4), 16); const b = parseInt(clean.substring(4, 6), 16); @@ -161,7 +161,7 @@ const Beams = ({ beamWidth = 2, beamHeight = 15, beamNumber = 12, - lightColor = '#ffffff', + lightColor = "#ffffff", speed = 2, noiseIntensity = 1.75, scale = 0.2, @@ -200,19 +200,19 @@ const Beams = ({ vec3 tangentZ = normalize(nextposZ - curpos); return normalize(cross(tangentZ, tangentX)); }`, - fragmentHeader: '', + fragmentHeader: "", vertex: { - '#include ': `transformed.z += getPos(transformed.xyz);`, - '#include ': `objectNormal = getNormal(position.xyz);`, + "#include ": `transformed.z += getPos(transformed.xyz);`, + "#include ": `objectNormal = getNormal(position.xyz);`, }, fragment: { - '#include ': ` + "#include ": ` float randomNoise = noise(gl_FragCoord.xy); gl_FragColor.rgb -= randomNoise / 15. * uNoiseIntensity;`, }, material: { fog: true }, uniforms: { - diffuse: new THREE.Color(...hexToNormalizedRGB('#000000')), + diffuse: new THREE.Color(...hexToNormalizedRGB("#000000")), time: { shared: true, mixed: true, linked: true, value: 0 }, roughness: 0.3, metalness: 0.3, @@ -222,7 +222,7 @@ const Beams = ({ uScale: scale, }, }), - [speed, noiseIntensity, scale] + [speed, noiseIntensity, scale], ); return ( @@ -238,7 +238,7 @@ const Beams = ({ - + ); @@ -249,7 +249,7 @@ function createStackedPlanesBufferGeometry( width, height, spacing, - heightSegments + heightSegments, ) { const geometry = new THREE.BufferGeometry(); const numVertices = n * (heightSegments + 1) * 2; @@ -278,7 +278,7 @@ function createStackedPlanesBufferGeometry( const uvY = j / heightSegments; uvs.set( [uvXOffset, uvY + uvYOffset, uvXOffset + 1, uvY + uvYOffset], - uvOffset + uvOffset, ); if (j < heightSegments) { @@ -294,8 +294,8 @@ function createStackedPlanesBufferGeometry( } } - geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); - geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2)); + geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3)); + geometry.setAttribute("uv", new THREE.BufferAttribute(uvs, 2)); geometry.setIndex(new THREE.BufferAttribute(indices, 1)); geometry.computeVertexNormals(); return geometry; @@ -306,14 +306,14 @@ const MergedPlanes = forwardRef(({ material, width, count, height }, ref) => { useImperativeHandle(ref, () => mesh.current); const geometry = useMemo( () => createStackedPlanesBufferGeometry(count, width, height, 0, 100), - [count, width, height] + [count, width, height], ); useFrame((_, delta) => { mesh.current.material.uniforms.time.value += 0.1 * delta; }); return ; }); -MergedPlanes.displayName = 'MergedPlanes'; +MergedPlanes.displayName = "MergedPlanes"; const PlaneNoise = forwardRef((props, ref) => ( ( height={props.height} /> )); -PlaneNoise.displayName = 'PlaneNoise'; +PlaneNoise.displayName = "PlaneNoise"; const DirLight = ({ position, color }) => { const dir = useRef(null); diff --git a/apps/docs/app/(home)/_components/hero.tsx b/apps/docs/app/(home)/_components/hero.tsx index 2791ac3..118bec8 100644 --- a/apps/docs/app/(home)/_components/hero.tsx +++ b/apps/docs/app/(home)/_components/hero.tsx @@ -15,7 +15,6 @@ export function Hero() { {/* Static background (shown when beams are off, e.g. reduced motion) */}
    -
    diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index 86344d9..21c8148 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -35,20 +35,6 @@ animation: aurora-shift 6s ease-in-out infinite; } -/* Fade a grid layer towards the edges */ -.grid-fade-mask { - -webkit-mask-image: radial-gradient( - ellipse 65% 55% at 50% 0%, - #000 55%, - transparent 100% - ); - mask-image: radial-gradient( - ellipse 65% 55% at 50% 0%, - #000 55%, - transparent 100% - ); -} - /* Rotating conic "border beam" around a card */ .beam-border { position: relative; From cef0085b81f244befe7ec04a83f0eec31654db07 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 06:42:31 +0000 Subject: [PATCH 10/11] chore(docs): pin three to 0.182 to silence THREE.Clock deprecation three r183 deprecated THREE.Clock, which @react-three/fiber 9 still uses internally, logging a console warning. Pin three to 0.182 (last pre-deprecation release; satisfies r3f/drei peer ranges) until r3f migrates to THREE.Timer. --- apps/docs/package.json | 10 +++++----- bun.lock | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/docs/package.json b/apps/docs/package.json index 03e81a6..abbc481 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -13,15 +13,15 @@ "@react-three/drei": "^10.7.7", "@react-three/fiber": "^9.6.1", "cnfast": "^0.0.8", + "fumadocs-core": "16.9.3", + "fumadocs-mdx": "15.0.10", + "fumadocs-ui": "16.9.3", + "lucide-react": "^0.544.0", "motion": "^11.18.1", "next": "16.2.7", "react": "catalog:", "react-dom": "catalog:", - "three": "^0.185.0", - "lucide-react": "^0.544.0", - "fumadocs-ui": "16.9.3", - "fumadocs-core": "16.9.3", - "fumadocs-mdx": "15.0.10", + "three": "0.182.0", "zod": "^4.4.3" }, "devDependencies": { diff --git a/bun.lock b/bun.lock index d0e7d78..b7f9333 100644 --- a/bun.lock +++ b/bun.lock @@ -29,7 +29,7 @@ "next": "16.2.7", "react": "catalog:", "react-dom": "catalog:", - "three": "^0.185.0", + "three": "0.182.0", "zod": "^4.4.3", }, "devDependencies": { @@ -2350,7 +2350,7 @@ "thread-stream": ["thread-stream@4.0.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA=="], - "three": ["three@0.185.0", "", {}, "sha512-+yRrcRO2iZa8uzvNNl0d7cL4huhgKgBvVJ0njcTe8xFqZ6DMAFZdCKDP91SEAuj25bNAj7k1QQdf+srZywVK6w=="], + "three": ["three@0.182.0", "", {}, "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ=="], "three-mesh-bvh": ["three-mesh-bvh@0.8.3", "", { "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg=="], From d9ee0d9341d079c240e2f4685248d7fd4ca6b3aa Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 07:13:18 +0000 Subject: [PATCH 11/11] feat(docs): add Vision logo (beam-V), drop the crystal-ball emoji MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an SVG mark — two mint beams forming a "V", echoing the hero background — and wire it into the docs nav and as the favicon. Replace the "🔮" in the README title with the centered logo. --- README.md | 5 ++++- apps/docs/app/icon.svg | 11 +++++++++++ apps/docs/lib/layout.shared.tsx | 22 ++++++++++++++-------- apps/docs/public/logo.svg | 11 +++++++++++ 4 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 apps/docs/app/icon.svg create mode 100644 apps/docs/public/logo.svg diff --git a/README.md b/README.md index 34447a3..0534c2e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# Vision 🔮 +
    + Vision logo +

    Vision

    +
    [![npm version](https://img.shields.io/npm/v/@getvision/server.svg)](https://www.npmjs.com/package/@getvision/server) [![npm downloads](https://img.shields.io/npm/dm/@getvision/server.svg)](https://www.npmjs.com/package/@getvision/server) diff --git a/apps/docs/app/icon.svg b/apps/docs/app/icon.svg new file mode 100644 index 0000000..6b00c0c --- /dev/null +++ b/apps/docs/app/icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/docs/lib/layout.shared.tsx b/apps/docs/lib/layout.shared.tsx index e2ebb22..62993ef 100644 --- a/apps/docs/lib/layout.shared.tsx +++ b/apps/docs/lib/layout.shared.tsx @@ -1,4 +1,4 @@ -import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; +import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; /** * Shared layout configurations @@ -10,7 +10,13 @@ import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; export function baseOptions(): BaseLayoutProps { return { nav: { - title: 'Vision', + title: ( + + {/* eslint-disable-next-line @next/next/no-img-element */} + + Vision + + ), }, // Dark theme only — hide the light/dark toggle themeSwitch: { @@ -18,16 +24,16 @@ export function baseOptions(): BaseLayoutProps { }, links: [ { - text: 'Documentation', - url: '/docs', - active: 'nested-url', + text: "Documentation", + url: "/docs", + active: "nested-url", }, { - text: 'GitHub', - url: 'https://github.com/ephor/vision', + text: "GitHub", + url: "https://github.com/ephor/vision", external: true, }, ], - githubUrl: 'https://github.com/ephor/vision', + githubUrl: "https://github.com/ephor/vision", }; } diff --git a/apps/docs/public/logo.svg b/apps/docs/public/logo.svg new file mode 100644 index 0000000..6b00c0c --- /dev/null +++ b/apps/docs/public/logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + +