├── README.md
├── docker
└── docker-compose.yaml
├── frontend
├── .gitignore
├── README.md
├── app
│ ├── api
│ │ └── chat
│ │ │ └── route.ts
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
├── components.json
├── components
│ ├── assistant-ui
│ │ ├── markdown-text.tsx
│ │ ├── thread-list.tsx
│ │ ├── thread.tsx
│ │ └── tooltip-icon-button.tsx
│ └── ui
│ │ ├── avatar.tsx
│ │ ├── button.tsx
│ │ └── tooltip.tsx
├── eslint.config.mjs
├── lib
│ └── utils.ts
├── next.config.ts
├── package.json
├── pnpm-lock.yaml
├── postcss.config.mjs
├── tailwind.config.ts
└── tsconfig.json
└── worker
├── .gitignore
├── drizzle.config.ts
├── package.json
├── pnpm-lock.yaml
├── src
├── db
│ └── schema.ts
├── index.ts
└── util
│ └── splitByLineStream.ts
├── tsconfig.json
└── wrangler.jsonc
/README.md:
--------------------------------------------------------------------------------
1 | # assistant-ui + ElectricSQL
2 |
3 | Resumable AI streams, built with:
4 |
5 | - assistant-ui
6 | - ElectricSQL
7 | - PostgreSQL
8 | - Cloudflare Workers
9 | - Drizzle ORM
10 |
11 | ## Getting started
12 |
13 | Start docker
14 |
15 | ```sh
16 | cd docker-compose && docker compose up
17 | ```
18 |
19 | Start backend
20 |
21 | ```sh
22 | cd worker && pnpm i && pnpm drizzle-kit push && pnpm run dev
23 | ```
24 |
25 | Start frontend
26 |
27 | ```sh
28 | cd frontend && pnpm i && pnpm run dev
29 | ```
30 |
--------------------------------------------------------------------------------
/docker/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | postgres:
3 | image: postgres:17-alpine
4 | environment:
5 | POSTGRES_DB: electric
6 | POSTGRES_USER: postgres
7 | POSTGRES_PASSWORD: password
8 | ports:
9 | - 54321:5432
10 | tmpfs:
11 | - /var/lib/postgresql/data
12 | - /tmp
13 | command:
14 | - -c
15 | - listen_addresses=*
16 | - -c
17 | - wal_level=logical
18 |
19 | electric:
20 | image: electricsql/electric
21 | environment:
22 | DATABASE_URL: postgresql://postgres:password@postgres:5432/electric?sslmode=disable
23 | ports:
24 | - "3000:3000"
25 | depends_on:
26 | - postgres
27 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 |
32 | # env files (can opt-in for commiting if needed)
33 | .env*
34 |
35 | # vercel
36 | .vercel
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | next-env.d.ts
41 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | This is the [assistant-ui](https://github.com/Yonom/assistant-ui) starter project.
2 |
3 | ## Getting Started
4 |
5 | First, add your OpenAI API key to `.env.local` file:
6 |
7 | ```
8 | OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
9 | ```
10 |
11 | Then, run the development server:
12 |
13 | ```bash
14 | npm run dev
15 | # or
16 | yarn dev
17 | # or
18 | pnpm dev
19 | # or
20 | bun dev
21 | ```
22 |
23 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
24 |
25 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
26 |
--------------------------------------------------------------------------------
/frontend/app/api/chat/route.ts:
--------------------------------------------------------------------------------
1 | import { openai } from "@ai-sdk/openai";
2 | import { jsonSchema, streamText } from "ai";
3 |
4 | export const maxDuration = 30;
5 |
6 | export async function POST(req: Request) {
7 | const { messages, system, tools } = await req.json();
8 |
9 | const result = streamText({
10 | model: openai("gpt-4o"),
11 | messages,
12 | system,
13 | tools: Object.fromEntries(
14 | Object.keys(tools).map((name) => [
15 | name,
16 | { ...tools[name], parameters: jsonSchema(tools[name].parameters) },
17 | ])
18 | ),
19 | });
20 |
21 | return result.toDataStreamResponse();
22 | }
23 |
--------------------------------------------------------------------------------
/frontend/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/assistant-ui/assistant-ui-electric/0b681604535bbb5bba859ebf16e24c8475b8e5b4/frontend/app/favicon.ico
--------------------------------------------------------------------------------
/frontend/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 | @layer base {
5 | :root {
6 | --background: 0 0% 100%;
7 | --foreground: 240 10% 3.9%;
8 | --card: 0 0% 100%;
9 | --card-foreground: 240 10% 3.9%;
10 | --popover: 0 0% 100%;
11 | --popover-foreground: 240 10% 3.9%;
12 | --primary: 240 5.9% 10%;
13 | --primary-foreground: 0 0% 98%;
14 | --secondary: 240 4.8% 95.9%;
15 | --secondary-foreground: 240 5.9% 10%;
16 | --muted: 240 4.8% 95.9%;
17 | --muted-foreground: 240 3.8% 46.1%;
18 | --accent: 240 4.8% 95.9%;
19 | --accent-foreground: 240 5.9% 10%;
20 | --destructive: 0 84.2% 60.2%;
21 | --destructive-foreground: 0 0% 98%;
22 | --border: 240 5.9% 90%;
23 | --input: 240 5.9% 90%;
24 | --ring: 240 10% 3.9%;
25 | --chart-1: 12 76% 61%;
26 | --chart-2: 173 58% 39%;
27 | --chart-3: 197 37% 24%;
28 | --chart-4: 43 74% 66%;
29 | --chart-5: 27 87% 67%;
30 | --radius: 0.5rem;
31 | }
32 | .dark {
33 | --background: 240 10% 3.9%;
34 | --foreground: 0 0% 98%;
35 | --card: 240 10% 3.9%;
36 | --card-foreground: 0 0% 98%;
37 | --popover: 240 10% 3.9%;
38 | --popover-foreground: 0 0% 98%;
39 | --primary: 0 0% 98%;
40 | --primary-foreground: 240 5.9% 10%;
41 | --secondary: 240 3.7% 15.9%;
42 | --secondary-foreground: 0 0% 98%;
43 | --muted: 240 3.7% 15.9%;
44 | --muted-foreground: 240 5% 64.9%;
45 | --accent: 240 3.7% 15.9%;
46 | --accent-foreground: 0 0% 98%;
47 | --destructive: 0 62.8% 30.6%;
48 | --destructive-foreground: 0 0% 98%;
49 | --border: 240 3.7% 15.9%;
50 | --input: 240 3.7% 15.9%;
51 | --ring: 240 4.9% 83.9%;
52 | --chart-1: 220 70% 50%;
53 | --chart-2: 160 60% 45%;
54 | --chart-3: 30 80% 55%;
55 | --chart-4: 280 65% 60%;
56 | --chart-5: 340 75% 55%;
57 | }
58 | }
59 | @layer base {
60 | * {
61 | @apply border-border;
62 | }
63 | body {
64 | @apply bg-background text-foreground;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/frontend/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Geist, Geist_Mono } from "next/font/google";
3 | import "./globals.css";
4 |
5 | const geistSans = Geist({
6 | variable: "--font-geist-sans",
7 | subsets: ["latin"],
8 | });
9 |
10 | const geistMono = Geist_Mono({
11 | variable: "--font-geist-mono",
12 | subsets: ["latin"],
13 | });
14 |
15 |
16 | export const metadata: Metadata = {
17 | title: "assistant-ui App",
18 | description: "Generated by create-assistant-ui",
19 | };
20 |
21 | export default function RootLayout({
22 | children,
23 | }: Readonly<{
24 | children: React.ReactNode;
25 | }>) {
26 | return (
27 |
28 |
31 | {children}
32 |
33 |
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/frontend/app/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { Thread } from "@/components/assistant-ui/thread";
3 | import {
4 | AssistantRuntimeProvider,
5 | TextContentPart,
6 | unstable_createMessageConverter,
7 | useExternalStoreRuntime,
8 | } from "@assistant-ui/react";
9 | import { useMemo, useState } from "react";
10 | import { parseDataStreamPart } from "ai";
11 | import { useShape } from "@electric-sql/react";
12 |
13 | const THREAD_ID = "TEST_THREAD_ID";
14 |
15 | type Message = {
16 | role: "user" | "assistant";
17 | content: [{ type: "text"; text: string }];
18 | };
19 |
20 | const { useThreadMessages } = unstable_createMessageConverter((m) => {
21 | return m;
22 | });
23 |
24 | type ThreadStreamColumn = {
25 | thread_id: string;
26 | sequence: number;
27 | payload: string;
28 | };
29 |
30 | type PayloadValue =
31 | | {
32 | type: "message";
33 | message: Message;
34 | }
35 | | {
36 | type: "ai-chunk";
37 | chunk: string;
38 | };
39 |
40 | const messagesFromChunks = (chunks: ThreadStreamColumn[]) => {
41 | const messages: Message[] = [];
42 |
43 | for (const chunk of chunks) {
44 | const payload = JSON.parse(chunk.payload) as PayloadValue;
45 | if (payload.type === "message") {
46 | messages.push(payload.message);
47 | } else if (payload.type === "ai-chunk") {
48 | const parsedChunk = parseDataStreamPart(payload.chunk);
49 | if (parsedChunk.type === "text") {
50 | const lastMessage = messages.at(-1);
51 | if (lastMessage?.role !== "assistant") {
52 | messages.push({
53 | role: "assistant",
54 | content: [{ type: "text", text: parsedChunk.value }],
55 | });
56 | } else {
57 | lastMessage.content[0].text += parsedChunk.value;
58 | }
59 | }
60 | }
61 | }
62 |
63 | return messages;
64 | };
65 |
66 | export default function Home() {
67 | const { data } = useShape({
68 | url: "http://localhost:3000/v1/shape",
69 | params: {
70 | table: "threads",
71 | columns: ["thread_id", "sequence", "payload"],
72 | where: `thread_id = '${THREAD_ID}'`,
73 | },
74 | });
75 |
76 | const messages = useMemo(() => messagesFromChunks(data), [data]);
77 |
78 | const [isRunning, setIsRunning] = useState(false);
79 |
80 | const threadMessages = useThreadMessages(messages, isRunning);
81 | const runtime = useExternalStoreRuntime({
82 | isRunning,
83 | messages: threadMessages,
84 | onNew: async (m) => {
85 | const newMessage: Message = {
86 | role: "user",
87 | content: [
88 | { type: "text", text: (m.content[0] as TextContentPart).text },
89 | ],
90 | };
91 | const newMessages = [...messages, newMessage];
92 |
93 | setIsRunning(true);
94 | try {
95 | await fetch("http://localhost:8787/api/chat", {
96 | method: "POST",
97 | body: JSON.stringify({
98 | thread_id: THREAD_ID,
99 | messages: newMessages,
100 | }),
101 | });
102 | } finally {
103 | setIsRunning(false);
104 | }
105 | },
106 | });
107 |
108 | return (
109 |
110 |
111 |
112 |
113 |
114 | );
115 | }
116 |
--------------------------------------------------------------------------------
/frontend/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "app/globals.css",
9 | "baseColor": "zinc",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks"
19 | },
20 | "iconLibrary": "lucide"
21 | }
--------------------------------------------------------------------------------
/frontend/components/assistant-ui/markdown-text.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import "@assistant-ui/react-markdown/styles/dot.css";
4 |
5 | import {
6 | CodeHeaderProps,
7 | MarkdownTextPrimitive,
8 | unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
9 | useIsMarkdownCodeBlock,
10 | } from "@assistant-ui/react-markdown";
11 | import remarkGfm from "remark-gfm";
12 | import { FC, memo, useState } from "react";
13 | import { CheckIcon, CopyIcon } from "lucide-react";
14 |
15 | import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
16 | import { cn } from "@/lib/utils";
17 |
18 | const MarkdownTextImpl = () => {
19 | return (
20 |
25 | );
26 | };
27 |
28 | export const MarkdownText = memo(MarkdownTextImpl);
29 |
30 | const CodeHeader: FC = ({ language, code }) => {
31 | const { isCopied, copyToClipboard } = useCopyToClipboard();
32 | const onCopy = () => {
33 | if (!code || isCopied) return;
34 | copyToClipboard(code);
35 | };
36 |
37 | return (
38 |
39 | {language}
40 |
41 | {!isCopied && }
42 | {isCopied && }
43 |
44 |
45 | );
46 | };
47 |
48 | const useCopyToClipboard = ({
49 | copiedDuration = 3000,
50 | }: {
51 | copiedDuration?: number;
52 | } = {}) => {
53 | const [isCopied, setIsCopied] = useState(false);
54 |
55 | const copyToClipboard = (value: string) => {
56 | if (!value) return;
57 |
58 | navigator.clipboard.writeText(value).then(() => {
59 | setIsCopied(true);
60 | setTimeout(() => setIsCopied(false), copiedDuration);
61 | });
62 | };
63 |
64 | return { isCopied, copyToClipboard };
65 | };
66 |
67 | const defaultComponents = memoizeMarkdownComponents({
68 | h1: ({ className, ...props }) => (
69 |
70 | ),
71 | h2: ({ className, ...props }) => (
72 |
73 | ),
74 | h3: ({ className, ...props }) => (
75 |
76 | ),
77 | h4: ({ className, ...props }) => (
78 |
79 | ),
80 | h5: ({ className, ...props }) => (
81 |
82 | ),
83 | h6: ({ className, ...props }) => (
84 |
85 | ),
86 | p: ({ className, ...props }) => (
87 |
88 | ),
89 | a: ({ className, ...props }) => (
90 |
91 | ),
92 | blockquote: ({ className, ...props }) => (
93 |
94 | ),
95 | ul: ({ className, ...props }) => (
96 | li]:mt-2", className)} {...props} />
97 | ),
98 | ol: ({ className, ...props }) => (
99 | li]:mt-2", className)} {...props} />
100 | ),
101 | hr: ({ className, ...props }) => (
102 |
103 | ),
104 | table: ({ className, ...props }) => (
105 |
106 | ),
107 | th: ({ className, ...props }) => (
108 | |
109 | ),
110 | td: ({ className, ...props }) => (
111 | |
112 | ),
113 | tr: ({ className, ...props }) => (
114 | td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg", className)} {...props} />
115 | ),
116 | sup: ({ className, ...props }) => (
117 | a]:text-xs [&>a]:no-underline", className)} {...props} />
118 | ),
119 | pre: ({ className, ...props }) => (
120 |
121 | ),
122 | code: function Code({ className, ...props }) {
123 | const isCodeBlock = useIsMarkdownCodeBlock();
124 | return (
125 |
129 | );
130 | },
131 | CodeHeader,
132 | });
133 |
--------------------------------------------------------------------------------
/frontend/components/assistant-ui/thread-list.tsx:
--------------------------------------------------------------------------------
1 | import type { FC } from "react";
2 | import {
3 | ThreadListItemPrimitive,
4 | ThreadListPrimitive,
5 | } from "@assistant-ui/react";
6 | import { ArchiveIcon, PlusIcon } from "lucide-react";
7 |
8 | import { Button } from "@/components/ui/button";
9 | import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
10 |
11 | export const ThreadList: FC = () => {
12 | return (
13 |
14 |
15 |
16 |
17 | );
18 | };
19 |
20 | const ThreadListNew: FC = () => {
21 | return (
22 |
23 |
27 |
28 | );
29 | };
30 |
31 | const ThreadListItems: FC = () => {
32 | return ;
33 | };
34 |
35 | const ThreadListItem: FC = () => {
36 | return (
37 |
38 |
39 |
40 |
41 |
42 |
43 | );
44 | };
45 |
46 | const ThreadListItemTitle: FC = () => {
47 | return (
48 |
49 |
50 |
51 | );
52 | };
53 |
54 | const ThreadListItemArchive: FC = () => {
55 | return (
56 |
57 |
62 |
63 |
64 |
65 | );
66 | };
67 |
--------------------------------------------------------------------------------
/frontend/components/assistant-ui/thread.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | ActionBarPrimitive,
3 | BranchPickerPrimitive,
4 | ComposerPrimitive,
5 | MessagePrimitive,
6 | ThreadPrimitive,
7 | } from "@assistant-ui/react";
8 | import type { FC } from "react";
9 | import {
10 | ArrowDownIcon,
11 | CheckIcon,
12 | ChevronLeftIcon,
13 | ChevronRightIcon,
14 | CopyIcon,
15 | PencilIcon,
16 | RefreshCwIcon,
17 | SendHorizontalIcon,
18 | } from "lucide-react";
19 | import { cn } from "@/lib/utils";
20 |
21 | import { Button } from "@/components/ui/button";
22 | import { MarkdownText } from "@/components/assistant-ui/markdown-text";
23 | import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
24 |
25 | export const Thread: FC = () => {
26 | return (
27 |
33 |
34 |
35 |
36 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | );
55 | };
56 |
57 | const ThreadScrollToBottom: FC = () => {
58 | return (
59 |
60 |
65 |
66 |
67 |
68 | );
69 | };
70 |
71 | const ThreadWelcome: FC = () => {
72 | return (
73 |
74 |
75 |
76 |
How can I help you today?
77 |
78 |
79 |
80 |
81 | );
82 | };
83 |
84 | const ThreadWelcomeSuggestions: FC = () => {
85 | return (
86 |
87 |
93 |
94 | What is the weather in Tokyo?
95 |
96 |
97 |
103 |
104 | What is assistant-ui?
105 |
106 |
107 |
108 | );
109 | };
110 |
111 | const Composer: FC = () => {
112 | return (
113 |
114 |
120 |
121 |
122 | );
123 | };
124 |
125 | const ComposerAction: FC = () => {
126 | return (
127 | <>
128 |
129 |
130 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
146 |
147 |
148 |
149 |
150 | >
151 | );
152 | };
153 |
154 | const UserMessage: FC = () => {
155 | return (
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | );
166 | };
167 |
168 | const UserActionBar: FC = () => {
169 | return (
170 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | );
182 | };
183 |
184 | const EditComposer: FC = () => {
185 | return (
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | );
199 | };
200 |
201 | const AssistantMessage: FC = () => {
202 | return (
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 | );
213 | };
214 |
215 | const AssistantActionBar: FC = () => {
216 | return (
217 |
223 | {/*
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 | */}
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 | );
254 | };
255 |
256 | const BranchPicker: FC = ({
257 | className,
258 | ...rest
259 | }) => {
260 | return (
261 |
269 |
270 |
271 |
272 |
273 |
274 |
275 | /
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 | );
284 | };
285 |
286 | const CircleStopIcon = () => {
287 | return (
288 |
297 | );
298 | };
299 |
--------------------------------------------------------------------------------
/frontend/components/assistant-ui/tooltip-icon-button.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { ComponentPropsWithoutRef, forwardRef } from "react";
4 |
5 | import {
6 | Tooltip,
7 | TooltipContent,
8 | TooltipProvider,
9 | TooltipTrigger,
10 | } from "@/components/ui/tooltip";
11 | import { Button } from "@/components/ui/button";
12 | import { cn } from "@/lib/utils";
13 |
14 | export type TooltipIconButtonProps = ComponentPropsWithoutRef & {
15 | tooltip: string;
16 | side?: "top" | "bottom" | "left" | "right";
17 | };
18 |
19 | export const TooltipIconButton = forwardRef<
20 | HTMLButtonElement,
21 | TooltipIconButtonProps
22 | >(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
23 | return (
24 |
25 |
26 |
27 |
37 |
38 | {tooltip}
39 |
40 |
41 | );
42 | });
43 |
44 | TooltipIconButton.displayName = "TooltipIconButton";
45 |
--------------------------------------------------------------------------------
/frontend/components/ui/avatar.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as AvatarPrimitive from "@radix-ui/react-avatar"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const Avatar = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, ...props }, ref) => (
12 |
20 | ))
21 | Avatar.displayName = AvatarPrimitive.Root.displayName
22 |
23 | const AvatarImage = React.forwardRef<
24 | React.ElementRef,
25 | React.ComponentPropsWithoutRef
26 | >(({ className, ...props }, ref) => (
27 |
32 | ))
33 | AvatarImage.displayName = AvatarPrimitive.Image.displayName
34 |
35 | const AvatarFallback = React.forwardRef<
36 | React.ElementRef,
37 | React.ComponentPropsWithoutRef
38 | >(({ className, ...props }, ref) => (
39 |
47 | ))
48 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
49 |
50 | export { Avatar, AvatarImage, AvatarFallback }
51 |
--------------------------------------------------------------------------------
/frontend/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Slot } from "@radix-ui/react-slot"
3 | import { cva, type VariantProps } from "class-variance-authority"
4 |
5 | import { cn } from "@/lib/utils"
6 |
7 | const buttonVariants = cva(
8 | "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
9 | {
10 | variants: {
11 | variant: {
12 | default:
13 | "bg-primary text-primary-foreground shadow hover:bg-primary/90",
14 | destructive:
15 | "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
16 | outline:
17 | "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
18 | secondary:
19 | "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
20 | ghost: "hover:bg-accent hover:text-accent-foreground",
21 | link: "text-primary underline-offset-4 hover:underline",
22 | },
23 | size: {
24 | default: "h-9 px-4 py-2",
25 | sm: "h-8 rounded-md px-3 text-xs",
26 | lg: "h-10 rounded-md px-8",
27 | icon: "h-9 w-9",
28 | },
29 | },
30 | defaultVariants: {
31 | variant: "default",
32 | size: "default",
33 | },
34 | }
35 | )
36 |
37 | export interface ButtonProps
38 | extends React.ButtonHTMLAttributes,
39 | VariantProps {
40 | asChild?: boolean
41 | }
42 |
43 | const Button = React.forwardRef(
44 | ({ className, variant, size, asChild = false, ...props }, ref) => {
45 | const Comp = asChild ? Slot : "button"
46 | return (
47 |
52 | )
53 | }
54 | )
55 | Button.displayName = "Button"
56 |
57 | export { Button, buttonVariants }
58 |
--------------------------------------------------------------------------------
/frontend/components/ui/tooltip.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as React from "react"
4 | import * as TooltipPrimitive from "@radix-ui/react-tooltip"
5 |
6 | import { cn } from "@/lib/utils"
7 |
8 | const TooltipProvider = TooltipPrimitive.Provider
9 |
10 | const Tooltip = TooltipPrimitive.Root
11 |
12 | const TooltipTrigger = TooltipPrimitive.Trigger
13 |
14 | const TooltipContent = React.forwardRef<
15 | React.ElementRef,
16 | React.ComponentPropsWithoutRef
17 | >(({ className, sideOffset = 4, ...props }, ref) => (
18 |
19 |
28 |
29 | ))
30 | TooltipContent.displayName = TooltipPrimitive.Content.displayName
31 |
32 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
33 |
--------------------------------------------------------------------------------
/frontend/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { dirname } from "path";
2 | import { fileURLToPath } from "url";
3 | import { FlatCompat } from "@eslint/eslintrc";
4 |
5 | const __filename = fileURLToPath(import.meta.url);
6 | const __dirname = dirname(__filename);
7 |
8 | const compat = new FlatCompat({
9 | baseDirectory: __dirname,
10 | });
11 |
12 | const eslintConfig = [
13 | ...compat.extends("next/core-web-vitals", "next/typescript"),
14 | ];
15 |
16 | export default eslintConfig;
17 |
--------------------------------------------------------------------------------
/frontend/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from "clsx";
2 | import { twMerge } from "tailwind-merge";
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
--------------------------------------------------------------------------------
/frontend/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "assistant-ui-starter",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev --turbo",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@ai-sdk/openai": "^1.1.15",
13 | "@assistant-ui/react": "^0.8.2",
14 | "@assistant-ui/react-ai-sdk": "^0.8.0",
15 | "@assistant-ui/react-markdown": "^0.8.0",
16 | "@electric-sql/react": "^1.0.0",
17 | "@radix-ui/react-avatar": "^1.1.3",
18 | "@radix-ui/react-slot": "^1.1.2",
19 | "@radix-ui/react-tooltip": "^1.1.8",
20 | "ai": "^4.1.46",
21 | "class-variance-authority": "^0.7.1",
22 | "clsx": "^2.1.1",
23 | "lucide-react": "^0.477.0",
24 | "next": "15.2.0",
25 | "react": "^19.0.0",
26 | "react-dom": "^19.0.0",
27 | "remark-gfm": "^4.0.1",
28 | "tailwind-merge": "^3.0.2",
29 | "tailwindcss-animate": "^1.0.7",
30 | "zod": "^3.24.2"
31 | },
32 | "devDependencies": {
33 | "@eslint/eslintrc": "^3",
34 | "@types/node": "^22",
35 | "@types/react": "^19",
36 | "@types/react-dom": "^19",
37 | "eslint": "^8",
38 | "eslint-config-next": "15.2.0",
39 | "postcss": "^8",
40 | "tailwindcss": "^3.4.1",
41 | "typescript": "^5"
42 | },
43 | "packageManager": "pnpm@10.6.3+sha512.bb45e34d50a9a76e858a95837301bfb6bd6d35aea2c5d52094fa497a467c43f5c440103ce2511e9e0a2f89c3d6071baac3358fc68ac6fb75e2ceb3d2736065e6",
44 | "pnpm": {
45 | "onlyBuiltDependencies": [
46 | "sharp"
47 | ]
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/frontend/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/frontend/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config = {
4 | darkMode: ["class"],
5 | content: [
6 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
8 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
9 | ],
10 | theme: {
11 | extend: {
12 | borderRadius: {
13 | lg: "var(--radius)",
14 | md: "calc(var(--radius) - 2px)",
15 | sm: "calc(var(--radius) - 4px)",
16 | },
17 | colors: {
18 | background: "hsl(var(--background))",
19 | foreground: "hsl(var(--foreground))",
20 | card: {
21 | DEFAULT: "hsl(var(--card))",
22 | foreground: "hsl(var(--card-foreground))",
23 | },
24 | popover: {
25 | DEFAULT: "hsl(var(--popover))",
26 | foreground: "hsl(var(--popover-foreground))",
27 | },
28 | primary: {
29 | DEFAULT: "hsl(var(--primary))",
30 | foreground: "hsl(var(--primary-foreground))",
31 | },
32 | secondary: {
33 | DEFAULT: "hsl(var(--secondary))",
34 | foreground: "hsl(var(--secondary-foreground))",
35 | },
36 | muted: {
37 | DEFAULT: "hsl(var(--muted))",
38 | foreground: "hsl(var(--muted-foreground))",
39 | },
40 | accent: {
41 | DEFAULT: "hsl(var(--accent))",
42 | foreground: "hsl(var(--accent-foreground))",
43 | },
44 | destructive: {
45 | DEFAULT: "hsl(var(--destructive))",
46 | foreground: "hsl(var(--destructive-foreground))",
47 | },
48 | border: "hsl(var(--border))",
49 | input: "hsl(var(--input))",
50 | ring: "hsl(var(--ring))",
51 | chart: {
52 | "1": "hsl(var(--chart-1))",
53 | "2": "hsl(var(--chart-2))",
54 | "3": "hsl(var(--chart-3))",
55 | "4": "hsl(var(--chart-4))",
56 | "5": "hsl(var(--chart-5))",
57 | },
58 | },
59 | },
60 | plugins: ['require("tailwindcss-animate")'],
61 | },
62 | } satisfies Config;
63 |
64 | export default config;
65 |
--------------------------------------------------------------------------------
/frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/worker/.gitignore:
--------------------------------------------------------------------------------
1 | # prod
2 | dist/
3 |
4 | # dev
5 | .yarn/
6 | !.yarn/releases
7 | .vscode/*
8 | !.vscode/launch.json
9 | !.vscode/*.code-snippets
10 | .idea/workspace.xml
11 | .idea/usage.statistics.xml
12 | .idea/shelf
13 |
14 | # deps
15 | node_modules/
16 | .wrangler
17 |
18 | # env
19 | .env
20 | .env.production
21 | .dev.vars
22 |
23 | # logs
24 | logs/
25 | *.log
26 | npm-debug.log*
27 | yarn-debug.log*
28 | yarn-error.log*
29 | pnpm-debug.log*
30 | lerna-debug.log*
31 |
32 | # misc
33 | .DS_Store
34 |
--------------------------------------------------------------------------------
/worker/drizzle.config.ts:
--------------------------------------------------------------------------------
1 | import 'dotenv/config';
2 | import { defineConfig } from 'drizzle-kit';
3 |
4 | export default defineConfig({
5 | out: './drizzle',
6 | schema: './src/db/schema.ts',
7 | dialect: 'postgresql',
8 | dbCredentials: {
9 | url: process.env.DATABASE_URL!,
10 | },
11 | });
12 |
--------------------------------------------------------------------------------
/worker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "worker",
3 | "scripts": {
4 | "dev": "wrangler dev",
5 | "deploy": "wrangler deploy --minify"
6 | },
7 | "dependencies": {
8 | "@ai-sdk/openai": "^1.2.5",
9 | "@electric-sql/client": "^1.0.0-beta.5",
10 | "@types/uuid": "^10.0.0",
11 | "ai": "^4.1.61",
12 | "dotenv": "^16.4.7",
13 | "drizzle-orm": "^0.40.0",
14 | "hono": "^4.7.4",
15 | "pg": "^8.14.0",
16 | "uuid": "^11.1.0",
17 | "zod": "^3.24.2"
18 | },
19 | "devDependencies": {
20 | "@cloudflare/workers-types": "^4.20250313.0",
21 | "@types/pg": "^8.11.11",
22 | "drizzle-kit": "^0.30.5",
23 | "tsx": "^4.19.3",
24 | "wrangler": "^4.0.0"
25 | },
26 | "packageManager": "pnpm@10.6.3"
27 | }
28 |
--------------------------------------------------------------------------------
/worker/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | '@ai-sdk/openai':
12 | specifier: ^1.2.5
13 | version: 1.2.5(zod@3.24.2)
14 | '@electric-sql/client':
15 | specifier: ^1.0.0-beta.5
16 | version: 1.0.0-beta.5
17 | '@types/uuid':
18 | specifier: ^10.0.0
19 | version: 10.0.0
20 | ai:
21 | specifier: ^4.1.61
22 | version: 4.1.61(react@19.0.0)(zod@3.24.2)
23 | dotenv:
24 | specifier: ^16.4.7
25 | version: 16.4.7
26 | drizzle-orm:
27 | specifier: ^0.40.0
28 | version: 0.40.0(@cloudflare/workers-types@4.20250313.0)(@opentelemetry/api@1.9.0)(@types/pg@8.11.11)(gel@2.0.1)(pg@8.14.0)
29 | hono:
30 | specifier: ^4.7.4
31 | version: 4.7.4
32 | pg:
33 | specifier: ^8.14.0
34 | version: 8.14.0
35 | uuid:
36 | specifier: ^11.1.0
37 | version: 11.1.0
38 | zod:
39 | specifier: ^3.24.2
40 | version: 3.24.2
41 | devDependencies:
42 | '@cloudflare/workers-types':
43 | specifier: ^4.20250313.0
44 | version: 4.20250313.0
45 | '@types/pg':
46 | specifier: ^8.11.11
47 | version: 8.11.11
48 | drizzle-kit:
49 | specifier: ^0.30.5
50 | version: 0.30.5
51 | tsx:
52 | specifier: ^4.19.3
53 | version: 4.19.3
54 | wrangler:
55 | specifier: ^4.0.0
56 | version: 4.0.0(@cloudflare/workers-types@4.20250313.0)
57 |
58 | packages:
59 |
60 | '@ai-sdk/openai@1.2.5':
61 | resolution: {integrity: sha512-COK7LzspgQQh5Yq070xfDdVMvp8WX592rXRaMaYNNqu1xpzahxDcM24aF9xgKYWuYH0UMoOw4UmWGwGxr6ygIg==}
62 | engines: {node: '>=18'}
63 | peerDependencies:
64 | zod: ^3.0.0
65 |
66 | '@ai-sdk/provider-utils@2.1.13':
67 | resolution: {integrity: sha512-kLjqsfOdONr6DGcGEntFYM1niXz1H05vyZNf9OAzK+KKKc64izyP4/q/9HX7W4+6g8hm6BnmKxu8vkr6FSOqDg==}
68 | engines: {node: '>=18'}
69 | peerDependencies:
70 | zod: ^3.0.0
71 | peerDependenciesMeta:
72 | zod:
73 | optional: true
74 |
75 | '@ai-sdk/provider@1.0.11':
76 | resolution: {integrity: sha512-CPyImHGiT3svyfmvPvAFTianZzWFtm0qK82XjwlQIA1C3IQ2iku/PMQXi7aFyrX0TyMh3VTkJPB03tjU2VXVrw==}
77 | engines: {node: '>=18'}
78 |
79 | '@ai-sdk/react@1.1.23':
80 | resolution: {integrity: sha512-R+PG9ya0GLs6orzt+1MxmjrWFuZM0gVs+l8ihBr1u+42wwkVeojY4CAtQjW4nrfGTVbdJYkl5y+r/VKfjr42aQ==}
81 | engines: {node: '>=18'}
82 | peerDependencies:
83 | react: ^18 || ^19 || ^19.0.0-rc
84 | zod: ^3.0.0
85 | peerDependenciesMeta:
86 | react:
87 | optional: true
88 | zod:
89 | optional: true
90 |
91 | '@ai-sdk/ui-utils@1.1.19':
92 | resolution: {integrity: sha512-rDHy2uxlPMt3jjS9L6mBrsfhEInZ5BVoWevmD13fsAt2s/XWy2OwwKmgmUQkdLlY4mn/eyeYAfDGK8+5CbOAgg==}
93 | engines: {node: '>=18'}
94 | peerDependencies:
95 | zod: ^3.0.0
96 | peerDependenciesMeta:
97 | zod:
98 | optional: true
99 |
100 | '@cloudflare/kv-asset-handler@0.4.0':
101 | resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==}
102 | engines: {node: '>=18.0.0'}
103 |
104 | '@cloudflare/unenv-preset@2.0.2':
105 | resolution: {integrity: sha512-nyzYnlZjjV5xT3LizahG1Iu6mnrCaxglJ04rZLpDwlDVDZ7v46lNsfxhV3A/xtfgQuSHmLnc6SVI+KwBpc3Lwg==}
106 | peerDependencies:
107 | unenv: 2.0.0-rc.14
108 | workerd: ^1.20250124.0
109 | peerDependenciesMeta:
110 | workerd:
111 | optional: true
112 |
113 | '@cloudflare/workerd-darwin-64@1.20250310.0':
114 | resolution: {integrity: sha512-LkLJO6F8lRNaCbK5sQCITi66SyCirDpffRuI5/5iILDJWQU4KVvAOKPvHrd4E5h/WDm9FGd22zMJwky7SxaNjg==}
115 | engines: {node: '>=16'}
116 | cpu: [x64]
117 | os: [darwin]
118 |
119 | '@cloudflare/workerd-darwin-arm64@1.20250310.0':
120 | resolution: {integrity: sha512-WythDJQbsU3Ii1hhA7pJZLBQlHezeYWAnaMnv3gS2Exj45oF8G4chFvrO7zCzjlcJXwSeBTtQRJqxw9AiUDhyA==}
121 | engines: {node: '>=16'}
122 | cpu: [arm64]
123 | os: [darwin]
124 |
125 | '@cloudflare/workerd-linux-64@1.20250310.0':
126 | resolution: {integrity: sha512-LbP769tT4/5QBHSj4lCt99QIKTi6cU+wYhLfF7rEtYHBnZS2+nIw9xttAzxeERx/aFrU+mxLcYPFV8fUeVxGng==}
127 | engines: {node: '>=16'}
128 | cpu: [x64]
129 | os: [linux]
130 |
131 | '@cloudflare/workerd-linux-arm64@1.20250310.0':
132 | resolution: {integrity: sha512-FzWeKM6id20EMZACaDg0Kkvg1C4lvXZgLBXVI6h6xaXTNFReoyEp4v4eMrRTuja5ec5k+m5iGKjP4/bMWJp9ew==}
133 | engines: {node: '>=16'}
134 | cpu: [arm64]
135 | os: [linux]
136 |
137 | '@cloudflare/workerd-windows-64@1.20250310.0':
138 | resolution: {integrity: sha512-04OgaDzm8/8nkjF3tovB+WywZLjSdAHCQT2omXKCwH3EDd1kpd8vvzE1pErtdIyKCOf9/sArY4BhPdxRj7ijlg==}
139 | engines: {node: '>=16'}
140 | cpu: [x64]
141 | os: [win32]
142 |
143 | '@cloudflare/workers-types@4.20250313.0':
144 | resolution: {integrity: sha512-iqyzZwogC+3yL8h58vMhjYQUHUZA8XazE3Q+ofR59wDOnsPe/u9W6+aCl408N0iNBhMPvpJQQ3/lkz0iJN2fhA==}
145 |
146 | '@cspotcode/source-map-support@0.8.1':
147 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
148 | engines: {node: '>=12'}
149 |
150 | '@drizzle-team/brocli@0.10.2':
151 | resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
152 |
153 | '@electric-sql/client@1.0.0-beta.5':
154 | resolution: {integrity: sha512-sP4yBBt4sDWE7FhMMVkVceKULLPStumFzlgltUqb7AzzXP6AK2qs4bZ2QrabY6feBgRgrMP19bOzxI/WOSnTAA==}
155 |
156 | '@emnapi/runtime@1.3.1':
157 | resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==}
158 |
159 | '@esbuild-kit/core-utils@3.3.2':
160 | resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==}
161 | deprecated: 'Merged into tsx: https://tsx.is'
162 |
163 | '@esbuild-kit/esm-loader@2.6.5':
164 | resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==}
165 | deprecated: 'Merged into tsx: https://tsx.is'
166 |
167 | '@esbuild/aix-ppc64@0.19.12':
168 | resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==}
169 | engines: {node: '>=12'}
170 | cpu: [ppc64]
171 | os: [aix]
172 |
173 | '@esbuild/aix-ppc64@0.24.2':
174 | resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
175 | engines: {node: '>=18'}
176 | cpu: [ppc64]
177 | os: [aix]
178 |
179 | '@esbuild/aix-ppc64@0.25.1':
180 | resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==}
181 | engines: {node: '>=18'}
182 | cpu: [ppc64]
183 | os: [aix]
184 |
185 | '@esbuild/android-arm64@0.18.20':
186 | resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
187 | engines: {node: '>=12'}
188 | cpu: [arm64]
189 | os: [android]
190 |
191 | '@esbuild/android-arm64@0.19.12':
192 | resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==}
193 | engines: {node: '>=12'}
194 | cpu: [arm64]
195 | os: [android]
196 |
197 | '@esbuild/android-arm64@0.24.2':
198 | resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==}
199 | engines: {node: '>=18'}
200 | cpu: [arm64]
201 | os: [android]
202 |
203 | '@esbuild/android-arm64@0.25.1':
204 | resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==}
205 | engines: {node: '>=18'}
206 | cpu: [arm64]
207 | os: [android]
208 |
209 | '@esbuild/android-arm@0.18.20':
210 | resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
211 | engines: {node: '>=12'}
212 | cpu: [arm]
213 | os: [android]
214 |
215 | '@esbuild/android-arm@0.19.12':
216 | resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==}
217 | engines: {node: '>=12'}
218 | cpu: [arm]
219 | os: [android]
220 |
221 | '@esbuild/android-arm@0.24.2':
222 | resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==}
223 | engines: {node: '>=18'}
224 | cpu: [arm]
225 | os: [android]
226 |
227 | '@esbuild/android-arm@0.25.1':
228 | resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==}
229 | engines: {node: '>=18'}
230 | cpu: [arm]
231 | os: [android]
232 |
233 | '@esbuild/android-x64@0.18.20':
234 | resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
235 | engines: {node: '>=12'}
236 | cpu: [x64]
237 | os: [android]
238 |
239 | '@esbuild/android-x64@0.19.12':
240 | resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==}
241 | engines: {node: '>=12'}
242 | cpu: [x64]
243 | os: [android]
244 |
245 | '@esbuild/android-x64@0.24.2':
246 | resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==}
247 | engines: {node: '>=18'}
248 | cpu: [x64]
249 | os: [android]
250 |
251 | '@esbuild/android-x64@0.25.1':
252 | resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==}
253 | engines: {node: '>=18'}
254 | cpu: [x64]
255 | os: [android]
256 |
257 | '@esbuild/darwin-arm64@0.18.20':
258 | resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
259 | engines: {node: '>=12'}
260 | cpu: [arm64]
261 | os: [darwin]
262 |
263 | '@esbuild/darwin-arm64@0.19.12':
264 | resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==}
265 | engines: {node: '>=12'}
266 | cpu: [arm64]
267 | os: [darwin]
268 |
269 | '@esbuild/darwin-arm64@0.24.2':
270 | resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==}
271 | engines: {node: '>=18'}
272 | cpu: [arm64]
273 | os: [darwin]
274 |
275 | '@esbuild/darwin-arm64@0.25.1':
276 | resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==}
277 | engines: {node: '>=18'}
278 | cpu: [arm64]
279 | os: [darwin]
280 |
281 | '@esbuild/darwin-x64@0.18.20':
282 | resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
283 | engines: {node: '>=12'}
284 | cpu: [x64]
285 | os: [darwin]
286 |
287 | '@esbuild/darwin-x64@0.19.12':
288 | resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==}
289 | engines: {node: '>=12'}
290 | cpu: [x64]
291 | os: [darwin]
292 |
293 | '@esbuild/darwin-x64@0.24.2':
294 | resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==}
295 | engines: {node: '>=18'}
296 | cpu: [x64]
297 | os: [darwin]
298 |
299 | '@esbuild/darwin-x64@0.25.1':
300 | resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==}
301 | engines: {node: '>=18'}
302 | cpu: [x64]
303 | os: [darwin]
304 |
305 | '@esbuild/freebsd-arm64@0.18.20':
306 | resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
307 | engines: {node: '>=12'}
308 | cpu: [arm64]
309 | os: [freebsd]
310 |
311 | '@esbuild/freebsd-arm64@0.19.12':
312 | resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==}
313 | engines: {node: '>=12'}
314 | cpu: [arm64]
315 | os: [freebsd]
316 |
317 | '@esbuild/freebsd-arm64@0.24.2':
318 | resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==}
319 | engines: {node: '>=18'}
320 | cpu: [arm64]
321 | os: [freebsd]
322 |
323 | '@esbuild/freebsd-arm64@0.25.1':
324 | resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==}
325 | engines: {node: '>=18'}
326 | cpu: [arm64]
327 | os: [freebsd]
328 |
329 | '@esbuild/freebsd-x64@0.18.20':
330 | resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
331 | engines: {node: '>=12'}
332 | cpu: [x64]
333 | os: [freebsd]
334 |
335 | '@esbuild/freebsd-x64@0.19.12':
336 | resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==}
337 | engines: {node: '>=12'}
338 | cpu: [x64]
339 | os: [freebsd]
340 |
341 | '@esbuild/freebsd-x64@0.24.2':
342 | resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==}
343 | engines: {node: '>=18'}
344 | cpu: [x64]
345 | os: [freebsd]
346 |
347 | '@esbuild/freebsd-x64@0.25.1':
348 | resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==}
349 | engines: {node: '>=18'}
350 | cpu: [x64]
351 | os: [freebsd]
352 |
353 | '@esbuild/linux-arm64@0.18.20':
354 | resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
355 | engines: {node: '>=12'}
356 | cpu: [arm64]
357 | os: [linux]
358 |
359 | '@esbuild/linux-arm64@0.19.12':
360 | resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==}
361 | engines: {node: '>=12'}
362 | cpu: [arm64]
363 | os: [linux]
364 |
365 | '@esbuild/linux-arm64@0.24.2':
366 | resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==}
367 | engines: {node: '>=18'}
368 | cpu: [arm64]
369 | os: [linux]
370 |
371 | '@esbuild/linux-arm64@0.25.1':
372 | resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==}
373 | engines: {node: '>=18'}
374 | cpu: [arm64]
375 | os: [linux]
376 |
377 | '@esbuild/linux-arm@0.18.20':
378 | resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
379 | engines: {node: '>=12'}
380 | cpu: [arm]
381 | os: [linux]
382 |
383 | '@esbuild/linux-arm@0.19.12':
384 | resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==}
385 | engines: {node: '>=12'}
386 | cpu: [arm]
387 | os: [linux]
388 |
389 | '@esbuild/linux-arm@0.24.2':
390 | resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==}
391 | engines: {node: '>=18'}
392 | cpu: [arm]
393 | os: [linux]
394 |
395 | '@esbuild/linux-arm@0.25.1':
396 | resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==}
397 | engines: {node: '>=18'}
398 | cpu: [arm]
399 | os: [linux]
400 |
401 | '@esbuild/linux-ia32@0.18.20':
402 | resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
403 | engines: {node: '>=12'}
404 | cpu: [ia32]
405 | os: [linux]
406 |
407 | '@esbuild/linux-ia32@0.19.12':
408 | resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==}
409 | engines: {node: '>=12'}
410 | cpu: [ia32]
411 | os: [linux]
412 |
413 | '@esbuild/linux-ia32@0.24.2':
414 | resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==}
415 | engines: {node: '>=18'}
416 | cpu: [ia32]
417 | os: [linux]
418 |
419 | '@esbuild/linux-ia32@0.25.1':
420 | resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==}
421 | engines: {node: '>=18'}
422 | cpu: [ia32]
423 | os: [linux]
424 |
425 | '@esbuild/linux-loong64@0.18.20':
426 | resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
427 | engines: {node: '>=12'}
428 | cpu: [loong64]
429 | os: [linux]
430 |
431 | '@esbuild/linux-loong64@0.19.12':
432 | resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==}
433 | engines: {node: '>=12'}
434 | cpu: [loong64]
435 | os: [linux]
436 |
437 | '@esbuild/linux-loong64@0.24.2':
438 | resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==}
439 | engines: {node: '>=18'}
440 | cpu: [loong64]
441 | os: [linux]
442 |
443 | '@esbuild/linux-loong64@0.25.1':
444 | resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==}
445 | engines: {node: '>=18'}
446 | cpu: [loong64]
447 | os: [linux]
448 |
449 | '@esbuild/linux-mips64el@0.18.20':
450 | resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
451 | engines: {node: '>=12'}
452 | cpu: [mips64el]
453 | os: [linux]
454 |
455 | '@esbuild/linux-mips64el@0.19.12':
456 | resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==}
457 | engines: {node: '>=12'}
458 | cpu: [mips64el]
459 | os: [linux]
460 |
461 | '@esbuild/linux-mips64el@0.24.2':
462 | resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==}
463 | engines: {node: '>=18'}
464 | cpu: [mips64el]
465 | os: [linux]
466 |
467 | '@esbuild/linux-mips64el@0.25.1':
468 | resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==}
469 | engines: {node: '>=18'}
470 | cpu: [mips64el]
471 | os: [linux]
472 |
473 | '@esbuild/linux-ppc64@0.18.20':
474 | resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
475 | engines: {node: '>=12'}
476 | cpu: [ppc64]
477 | os: [linux]
478 |
479 | '@esbuild/linux-ppc64@0.19.12':
480 | resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==}
481 | engines: {node: '>=12'}
482 | cpu: [ppc64]
483 | os: [linux]
484 |
485 | '@esbuild/linux-ppc64@0.24.2':
486 | resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==}
487 | engines: {node: '>=18'}
488 | cpu: [ppc64]
489 | os: [linux]
490 |
491 | '@esbuild/linux-ppc64@0.25.1':
492 | resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==}
493 | engines: {node: '>=18'}
494 | cpu: [ppc64]
495 | os: [linux]
496 |
497 | '@esbuild/linux-riscv64@0.18.20':
498 | resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
499 | engines: {node: '>=12'}
500 | cpu: [riscv64]
501 | os: [linux]
502 |
503 | '@esbuild/linux-riscv64@0.19.12':
504 | resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==}
505 | engines: {node: '>=12'}
506 | cpu: [riscv64]
507 | os: [linux]
508 |
509 | '@esbuild/linux-riscv64@0.24.2':
510 | resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==}
511 | engines: {node: '>=18'}
512 | cpu: [riscv64]
513 | os: [linux]
514 |
515 | '@esbuild/linux-riscv64@0.25.1':
516 | resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==}
517 | engines: {node: '>=18'}
518 | cpu: [riscv64]
519 | os: [linux]
520 |
521 | '@esbuild/linux-s390x@0.18.20':
522 | resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
523 | engines: {node: '>=12'}
524 | cpu: [s390x]
525 | os: [linux]
526 |
527 | '@esbuild/linux-s390x@0.19.12':
528 | resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==}
529 | engines: {node: '>=12'}
530 | cpu: [s390x]
531 | os: [linux]
532 |
533 | '@esbuild/linux-s390x@0.24.2':
534 | resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==}
535 | engines: {node: '>=18'}
536 | cpu: [s390x]
537 | os: [linux]
538 |
539 | '@esbuild/linux-s390x@0.25.1':
540 | resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==}
541 | engines: {node: '>=18'}
542 | cpu: [s390x]
543 | os: [linux]
544 |
545 | '@esbuild/linux-x64@0.18.20':
546 | resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
547 | engines: {node: '>=12'}
548 | cpu: [x64]
549 | os: [linux]
550 |
551 | '@esbuild/linux-x64@0.19.12':
552 | resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==}
553 | engines: {node: '>=12'}
554 | cpu: [x64]
555 | os: [linux]
556 |
557 | '@esbuild/linux-x64@0.24.2':
558 | resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==}
559 | engines: {node: '>=18'}
560 | cpu: [x64]
561 | os: [linux]
562 |
563 | '@esbuild/linux-x64@0.25.1':
564 | resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==}
565 | engines: {node: '>=18'}
566 | cpu: [x64]
567 | os: [linux]
568 |
569 | '@esbuild/netbsd-arm64@0.24.2':
570 | resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==}
571 | engines: {node: '>=18'}
572 | cpu: [arm64]
573 | os: [netbsd]
574 |
575 | '@esbuild/netbsd-arm64@0.25.1':
576 | resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==}
577 | engines: {node: '>=18'}
578 | cpu: [arm64]
579 | os: [netbsd]
580 |
581 | '@esbuild/netbsd-x64@0.18.20':
582 | resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
583 | engines: {node: '>=12'}
584 | cpu: [x64]
585 | os: [netbsd]
586 |
587 | '@esbuild/netbsd-x64@0.19.12':
588 | resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==}
589 | engines: {node: '>=12'}
590 | cpu: [x64]
591 | os: [netbsd]
592 |
593 | '@esbuild/netbsd-x64@0.24.2':
594 | resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==}
595 | engines: {node: '>=18'}
596 | cpu: [x64]
597 | os: [netbsd]
598 |
599 | '@esbuild/netbsd-x64@0.25.1':
600 | resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==}
601 | engines: {node: '>=18'}
602 | cpu: [x64]
603 | os: [netbsd]
604 |
605 | '@esbuild/openbsd-arm64@0.24.2':
606 | resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==}
607 | engines: {node: '>=18'}
608 | cpu: [arm64]
609 | os: [openbsd]
610 |
611 | '@esbuild/openbsd-arm64@0.25.1':
612 | resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==}
613 | engines: {node: '>=18'}
614 | cpu: [arm64]
615 | os: [openbsd]
616 |
617 | '@esbuild/openbsd-x64@0.18.20':
618 | resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
619 | engines: {node: '>=12'}
620 | cpu: [x64]
621 | os: [openbsd]
622 |
623 | '@esbuild/openbsd-x64@0.19.12':
624 | resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==}
625 | engines: {node: '>=12'}
626 | cpu: [x64]
627 | os: [openbsd]
628 |
629 | '@esbuild/openbsd-x64@0.24.2':
630 | resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==}
631 | engines: {node: '>=18'}
632 | cpu: [x64]
633 | os: [openbsd]
634 |
635 | '@esbuild/openbsd-x64@0.25.1':
636 | resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==}
637 | engines: {node: '>=18'}
638 | cpu: [x64]
639 | os: [openbsd]
640 |
641 | '@esbuild/sunos-x64@0.18.20':
642 | resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
643 | engines: {node: '>=12'}
644 | cpu: [x64]
645 | os: [sunos]
646 |
647 | '@esbuild/sunos-x64@0.19.12':
648 | resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==}
649 | engines: {node: '>=12'}
650 | cpu: [x64]
651 | os: [sunos]
652 |
653 | '@esbuild/sunos-x64@0.24.2':
654 | resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==}
655 | engines: {node: '>=18'}
656 | cpu: [x64]
657 | os: [sunos]
658 |
659 | '@esbuild/sunos-x64@0.25.1':
660 | resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==}
661 | engines: {node: '>=18'}
662 | cpu: [x64]
663 | os: [sunos]
664 |
665 | '@esbuild/win32-arm64@0.18.20':
666 | resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
667 | engines: {node: '>=12'}
668 | cpu: [arm64]
669 | os: [win32]
670 |
671 | '@esbuild/win32-arm64@0.19.12':
672 | resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==}
673 | engines: {node: '>=12'}
674 | cpu: [arm64]
675 | os: [win32]
676 |
677 | '@esbuild/win32-arm64@0.24.2':
678 | resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==}
679 | engines: {node: '>=18'}
680 | cpu: [arm64]
681 | os: [win32]
682 |
683 | '@esbuild/win32-arm64@0.25.1':
684 | resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==}
685 | engines: {node: '>=18'}
686 | cpu: [arm64]
687 | os: [win32]
688 |
689 | '@esbuild/win32-ia32@0.18.20':
690 | resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
691 | engines: {node: '>=12'}
692 | cpu: [ia32]
693 | os: [win32]
694 |
695 | '@esbuild/win32-ia32@0.19.12':
696 | resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==}
697 | engines: {node: '>=12'}
698 | cpu: [ia32]
699 | os: [win32]
700 |
701 | '@esbuild/win32-ia32@0.24.2':
702 | resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==}
703 | engines: {node: '>=18'}
704 | cpu: [ia32]
705 | os: [win32]
706 |
707 | '@esbuild/win32-ia32@0.25.1':
708 | resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==}
709 | engines: {node: '>=18'}
710 | cpu: [ia32]
711 | os: [win32]
712 |
713 | '@esbuild/win32-x64@0.18.20':
714 | resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
715 | engines: {node: '>=12'}
716 | cpu: [x64]
717 | os: [win32]
718 |
719 | '@esbuild/win32-x64@0.19.12':
720 | resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==}
721 | engines: {node: '>=12'}
722 | cpu: [x64]
723 | os: [win32]
724 |
725 | '@esbuild/win32-x64@0.24.2':
726 | resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==}
727 | engines: {node: '>=18'}
728 | cpu: [x64]
729 | os: [win32]
730 |
731 | '@esbuild/win32-x64@0.25.1':
732 | resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==}
733 | engines: {node: '>=18'}
734 | cpu: [x64]
735 | os: [win32]
736 |
737 | '@fastify/busboy@2.1.1':
738 | resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
739 | engines: {node: '>=14'}
740 |
741 | '@img/sharp-darwin-arm64@0.33.5':
742 | resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
743 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
744 | cpu: [arm64]
745 | os: [darwin]
746 |
747 | '@img/sharp-darwin-x64@0.33.5':
748 | resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
749 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
750 | cpu: [x64]
751 | os: [darwin]
752 |
753 | '@img/sharp-libvips-darwin-arm64@1.0.4':
754 | resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
755 | cpu: [arm64]
756 | os: [darwin]
757 |
758 | '@img/sharp-libvips-darwin-x64@1.0.4':
759 | resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
760 | cpu: [x64]
761 | os: [darwin]
762 |
763 | '@img/sharp-libvips-linux-arm64@1.0.4':
764 | resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
765 | cpu: [arm64]
766 | os: [linux]
767 |
768 | '@img/sharp-libvips-linux-arm@1.0.5':
769 | resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
770 | cpu: [arm]
771 | os: [linux]
772 |
773 | '@img/sharp-libvips-linux-s390x@1.0.4':
774 | resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
775 | cpu: [s390x]
776 | os: [linux]
777 |
778 | '@img/sharp-libvips-linux-x64@1.0.4':
779 | resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
780 | cpu: [x64]
781 | os: [linux]
782 |
783 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
784 | resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
785 | cpu: [arm64]
786 | os: [linux]
787 |
788 | '@img/sharp-libvips-linuxmusl-x64@1.0.4':
789 | resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
790 | cpu: [x64]
791 | os: [linux]
792 |
793 | '@img/sharp-linux-arm64@0.33.5':
794 | resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
795 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
796 | cpu: [arm64]
797 | os: [linux]
798 |
799 | '@img/sharp-linux-arm@0.33.5':
800 | resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
801 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
802 | cpu: [arm]
803 | os: [linux]
804 |
805 | '@img/sharp-linux-s390x@0.33.5':
806 | resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
807 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
808 | cpu: [s390x]
809 | os: [linux]
810 |
811 | '@img/sharp-linux-x64@0.33.5':
812 | resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
813 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
814 | cpu: [x64]
815 | os: [linux]
816 |
817 | '@img/sharp-linuxmusl-arm64@0.33.5':
818 | resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
819 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
820 | cpu: [arm64]
821 | os: [linux]
822 |
823 | '@img/sharp-linuxmusl-x64@0.33.5':
824 | resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
825 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
826 | cpu: [x64]
827 | os: [linux]
828 |
829 | '@img/sharp-wasm32@0.33.5':
830 | resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
831 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
832 | cpu: [wasm32]
833 |
834 | '@img/sharp-win32-ia32@0.33.5':
835 | resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
836 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
837 | cpu: [ia32]
838 | os: [win32]
839 |
840 | '@img/sharp-win32-x64@0.33.5':
841 | resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
842 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
843 | cpu: [x64]
844 | os: [win32]
845 |
846 | '@jridgewell/resolve-uri@3.1.2':
847 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
848 | engines: {node: '>=6.0.0'}
849 |
850 | '@jridgewell/sourcemap-codec@1.5.0':
851 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
852 |
853 | '@jridgewell/trace-mapping@0.3.9':
854 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
855 |
856 | '@opentelemetry/api@1.9.0':
857 | resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
858 | engines: {node: '>=8.0.0'}
859 |
860 | '@petamoriken/float16@3.9.2':
861 | resolution: {integrity: sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==}
862 |
863 | '@rollup/rollup-darwin-arm64@4.35.0':
864 | resolution: {integrity: sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==}
865 | cpu: [arm64]
866 | os: [darwin]
867 |
868 | '@types/diff-match-patch@1.0.36':
869 | resolution: {integrity: sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==}
870 |
871 | '@types/node@22.13.10':
872 | resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==}
873 |
874 | '@types/pg@8.11.11':
875 | resolution: {integrity: sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==}
876 |
877 | '@types/uuid@10.0.0':
878 | resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==}
879 |
880 | acorn-walk@8.3.2:
881 | resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
882 | engines: {node: '>=0.4.0'}
883 |
884 | acorn@8.14.0:
885 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
886 | engines: {node: '>=0.4.0'}
887 | hasBin: true
888 |
889 | ai@4.1.61:
890 | resolution: {integrity: sha512-Y9SAyGJEeW23F6C7PSHZXYNEvbH2cqJm0rVW2AoeFaXFT13ttx8rAqs8wz2w466C1UB329yl5PXayFcHqofSEA==}
891 | engines: {node: '>=18'}
892 | peerDependencies:
893 | react: ^18 || ^19 || ^19.0.0-rc
894 | zod: ^3.0.0
895 | peerDependenciesMeta:
896 | react:
897 | optional: true
898 | zod:
899 | optional: true
900 |
901 | as-table@1.0.55:
902 | resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
903 |
904 | blake3-wasm@2.1.5:
905 | resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
906 |
907 | buffer-from@1.1.2:
908 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
909 |
910 | chalk@5.4.1:
911 | resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
912 | engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
913 |
914 | color-convert@2.0.1:
915 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
916 | engines: {node: '>=7.0.0'}
917 |
918 | color-name@1.1.4:
919 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
920 |
921 | color-string@1.9.1:
922 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
923 |
924 | color@4.2.3:
925 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
926 | engines: {node: '>=12.5.0'}
927 |
928 | cookie@0.5.0:
929 | resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
930 | engines: {node: '>= 0.6'}
931 |
932 | data-uri-to-buffer@2.0.2:
933 | resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
934 |
935 | debug@4.4.0:
936 | resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
937 | engines: {node: '>=6.0'}
938 | peerDependencies:
939 | supports-color: '*'
940 | peerDependenciesMeta:
941 | supports-color:
942 | optional: true
943 |
944 | defu@6.1.4:
945 | resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
946 |
947 | dequal@2.0.3:
948 | resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
949 | engines: {node: '>=6'}
950 |
951 | detect-libc@2.0.3:
952 | resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
953 | engines: {node: '>=8'}
954 |
955 | diff-match-patch@1.0.5:
956 | resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==}
957 |
958 | dotenv@16.4.7:
959 | resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
960 | engines: {node: '>=12'}
961 |
962 | drizzle-kit@0.30.5:
963 | resolution: {integrity: sha512-l6dMSE100u7sDaTbLczibrQZjA35jLsHNqIV+jmhNVO3O8jzM6kywMOmV9uOz9ZVSCMPQhAZEFjL/qDPVrqpUA==}
964 | hasBin: true
965 |
966 | drizzle-orm@0.40.0:
967 | resolution: {integrity: sha512-7ptk/HQiMSrEZHnAsSlBESXWj52VwgMmyTEfoNmpNN2ZXpcz13LwHfXTIghsAEud7Z5UJhDOp8U07ujcqme7wg==}
968 | peerDependencies:
969 | '@aws-sdk/client-rds-data': '>=3'
970 | '@cloudflare/workers-types': '>=4'
971 | '@electric-sql/pglite': '>=0.2.0'
972 | '@libsql/client': '>=0.10.0'
973 | '@libsql/client-wasm': '>=0.10.0'
974 | '@neondatabase/serverless': '>=0.10.0'
975 | '@op-engineering/op-sqlite': '>=2'
976 | '@opentelemetry/api': ^1.4.1
977 | '@planetscale/database': '>=1'
978 | '@prisma/client': '*'
979 | '@tidbcloud/serverless': '*'
980 | '@types/better-sqlite3': '*'
981 | '@types/pg': '*'
982 | '@types/sql.js': '*'
983 | '@vercel/postgres': '>=0.8.0'
984 | '@xata.io/client': '*'
985 | better-sqlite3: '>=7'
986 | bun-types: '*'
987 | expo-sqlite: '>=14.0.0'
988 | gel: '>=2'
989 | knex: '*'
990 | kysely: '*'
991 | mysql2: '>=2'
992 | pg: '>=8'
993 | postgres: '>=3'
994 | prisma: '*'
995 | sql.js: '>=1'
996 | sqlite3: '>=5'
997 | peerDependenciesMeta:
998 | '@aws-sdk/client-rds-data':
999 | optional: true
1000 | '@cloudflare/workers-types':
1001 | optional: true
1002 | '@electric-sql/pglite':
1003 | optional: true
1004 | '@libsql/client':
1005 | optional: true
1006 | '@libsql/client-wasm':
1007 | optional: true
1008 | '@neondatabase/serverless':
1009 | optional: true
1010 | '@op-engineering/op-sqlite':
1011 | optional: true
1012 | '@opentelemetry/api':
1013 | optional: true
1014 | '@planetscale/database':
1015 | optional: true
1016 | '@prisma/client':
1017 | optional: true
1018 | '@tidbcloud/serverless':
1019 | optional: true
1020 | '@types/better-sqlite3':
1021 | optional: true
1022 | '@types/pg':
1023 | optional: true
1024 | '@types/sql.js':
1025 | optional: true
1026 | '@vercel/postgres':
1027 | optional: true
1028 | '@xata.io/client':
1029 | optional: true
1030 | better-sqlite3:
1031 | optional: true
1032 | bun-types:
1033 | optional: true
1034 | expo-sqlite:
1035 | optional: true
1036 | gel:
1037 | optional: true
1038 | knex:
1039 | optional: true
1040 | kysely:
1041 | optional: true
1042 | mysql2:
1043 | optional: true
1044 | pg:
1045 | optional: true
1046 | postgres:
1047 | optional: true
1048 | prisma:
1049 | optional: true
1050 | sql.js:
1051 | optional: true
1052 | sqlite3:
1053 | optional: true
1054 |
1055 | env-paths@3.0.0:
1056 | resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==}
1057 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
1058 |
1059 | esbuild-register@3.6.0:
1060 | resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==}
1061 | peerDependencies:
1062 | esbuild: '>=0.12 <1'
1063 |
1064 | esbuild@0.18.20:
1065 | resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
1066 | engines: {node: '>=12'}
1067 | hasBin: true
1068 |
1069 | esbuild@0.19.12:
1070 | resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==}
1071 | engines: {node: '>=12'}
1072 | hasBin: true
1073 |
1074 | esbuild@0.24.2:
1075 | resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==}
1076 | engines: {node: '>=18'}
1077 | hasBin: true
1078 |
1079 | esbuild@0.25.1:
1080 | resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==}
1081 | engines: {node: '>=18'}
1082 | hasBin: true
1083 |
1084 | eventsource-parser@3.0.0:
1085 | resolution: {integrity: sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==}
1086 | engines: {node: '>=18.0.0'}
1087 |
1088 | exit-hook@2.2.1:
1089 | resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==}
1090 | engines: {node: '>=6'}
1091 |
1092 | exsolve@1.0.4:
1093 | resolution: {integrity: sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==}
1094 |
1095 | fsevents@2.3.3:
1096 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
1097 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
1098 | os: [darwin]
1099 |
1100 | gel@2.0.1:
1101 | resolution: {integrity: sha512-gfem3IGvqKqXwEq7XseBogyaRwGsQGuE7Cw/yQsjLGdgiyqX92G1xENPCE0ltunPGcsJIa6XBOTx/PK169mOqw==}
1102 | engines: {node: '>= 18.0.0'}
1103 | hasBin: true
1104 |
1105 | get-source@2.0.12:
1106 | resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
1107 |
1108 | get-tsconfig@4.10.0:
1109 | resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==}
1110 |
1111 | glob-to-regexp@0.4.1:
1112 | resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
1113 |
1114 | hono@4.7.4:
1115 | resolution: {integrity: sha512-Pst8FuGqz3L7tFF+u9Pu70eI0xa5S3LPUmrNd5Jm8nTHze9FxLTK9Kaj5g/k4UcwuJSXTP65SyHOPLrffpcAJg==}
1116 | engines: {node: '>=16.9.0'}
1117 |
1118 | is-arrayish@0.3.2:
1119 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
1120 |
1121 | isexe@3.1.1:
1122 | resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
1123 | engines: {node: '>=16'}
1124 |
1125 | json-schema@0.4.0:
1126 | resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
1127 |
1128 | jsondiffpatch@0.6.0:
1129 | resolution: {integrity: sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==}
1130 | engines: {node: ^18.0.0 || >=20.0.0}
1131 | hasBin: true
1132 |
1133 | mime@3.0.0:
1134 | resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==}
1135 | engines: {node: '>=10.0.0'}
1136 | hasBin: true
1137 |
1138 | miniflare@4.20250310.0:
1139 | resolution: {integrity: sha512-WL4hKQIfXyTxKyQzxJyyy/v+OYSiF51s3Qe1Q4W4MjHJbtiN8Kg7+oeTdHYgqYehanN2zYoSKJ/xooIy8q5+XA==}
1140 | engines: {node: '>=18.0.0'}
1141 | hasBin: true
1142 |
1143 | ms@2.1.3:
1144 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
1145 |
1146 | mustache@4.2.0:
1147 | resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==}
1148 | hasBin: true
1149 |
1150 | nanoid@3.3.10:
1151 | resolution: {integrity: sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==}
1152 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1153 | hasBin: true
1154 |
1155 | obuf@1.1.2:
1156 | resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==}
1157 |
1158 | ohash@2.0.11:
1159 | resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
1160 |
1161 | path-to-regexp@6.3.0:
1162 | resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
1163 |
1164 | pathe@2.0.3:
1165 | resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
1166 |
1167 | pg-cloudflare@1.1.1:
1168 | resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==}
1169 |
1170 | pg-connection-string@2.7.0:
1171 | resolution: {integrity: sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==}
1172 |
1173 | pg-int8@1.0.1:
1174 | resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
1175 | engines: {node: '>=4.0.0'}
1176 |
1177 | pg-numeric@1.0.2:
1178 | resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==}
1179 | engines: {node: '>=4'}
1180 |
1181 | pg-pool@3.8.0:
1182 | resolution: {integrity: sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==}
1183 | peerDependencies:
1184 | pg: '>=8.0'
1185 |
1186 | pg-protocol@1.8.0:
1187 | resolution: {integrity: sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==}
1188 |
1189 | pg-types@2.2.0:
1190 | resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
1191 | engines: {node: '>=4'}
1192 |
1193 | pg-types@4.0.2:
1194 | resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==}
1195 | engines: {node: '>=10'}
1196 |
1197 | pg@8.14.0:
1198 | resolution: {integrity: sha512-nXbVpyoaXVmdqlKEzToFf37qzyeeh7mbiXsnoWvstSqohj88yaa/I/Rq/HEVn2QPSZEuLIJa/jSpRDyzjEx4FQ==}
1199 | engines: {node: '>= 8.0.0'}
1200 | peerDependencies:
1201 | pg-native: '>=3.0.1'
1202 | peerDependenciesMeta:
1203 | pg-native:
1204 | optional: true
1205 |
1206 | pgpass@1.0.5:
1207 | resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
1208 |
1209 | postgres-array@2.0.0:
1210 | resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
1211 | engines: {node: '>=4'}
1212 |
1213 | postgres-array@3.0.4:
1214 | resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==}
1215 | engines: {node: '>=12'}
1216 |
1217 | postgres-bytea@1.0.0:
1218 | resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==}
1219 | engines: {node: '>=0.10.0'}
1220 |
1221 | postgres-bytea@3.0.0:
1222 | resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==}
1223 | engines: {node: '>= 6'}
1224 |
1225 | postgres-date@1.0.7:
1226 | resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
1227 | engines: {node: '>=0.10.0'}
1228 |
1229 | postgres-date@2.1.0:
1230 | resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==}
1231 | engines: {node: '>=12'}
1232 |
1233 | postgres-interval@1.2.0:
1234 | resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
1235 | engines: {node: '>=0.10.0'}
1236 |
1237 | postgres-interval@3.0.0:
1238 | resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==}
1239 | engines: {node: '>=12'}
1240 |
1241 | postgres-range@1.1.4:
1242 | resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==}
1243 |
1244 | printable-characters@1.0.42:
1245 | resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
1246 |
1247 | react@19.0.0:
1248 | resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
1249 | engines: {node: '>=0.10.0'}
1250 |
1251 | resolve-pkg-maps@1.0.0:
1252 | resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
1253 |
1254 | secure-json-parse@2.7.0:
1255 | resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
1256 |
1257 | semver@7.7.1:
1258 | resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
1259 | engines: {node: '>=10'}
1260 | hasBin: true
1261 |
1262 | sharp@0.33.5:
1263 | resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
1264 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1265 |
1266 | shell-quote@1.8.2:
1267 | resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==}
1268 | engines: {node: '>= 0.4'}
1269 |
1270 | simple-swizzle@0.2.2:
1271 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
1272 |
1273 | source-map-support@0.5.21:
1274 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
1275 |
1276 | source-map@0.6.1:
1277 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
1278 | engines: {node: '>=0.10.0'}
1279 |
1280 | split2@4.2.0:
1281 | resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
1282 | engines: {node: '>= 10.x'}
1283 |
1284 | stacktracey@2.1.8:
1285 | resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==}
1286 |
1287 | stoppable@1.1.0:
1288 | resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==}
1289 | engines: {node: '>=4', npm: '>=6'}
1290 |
1291 | swr@2.3.3:
1292 | resolution: {integrity: sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A==}
1293 | peerDependencies:
1294 | react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1295 |
1296 | throttleit@2.1.0:
1297 | resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==}
1298 | engines: {node: '>=18'}
1299 |
1300 | tslib@2.8.1:
1301 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
1302 |
1303 | tsx@4.19.3:
1304 | resolution: {integrity: sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==}
1305 | engines: {node: '>=18.0.0'}
1306 | hasBin: true
1307 |
1308 | ufo@1.5.4:
1309 | resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
1310 |
1311 | undici-types@6.20.0:
1312 | resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
1313 |
1314 | undici@5.28.5:
1315 | resolution: {integrity: sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==}
1316 | engines: {node: '>=14.0'}
1317 |
1318 | unenv@2.0.0-rc.14:
1319 | resolution: {integrity: sha512-od496pShMen7nOy5VmVJCnq8rptd45vh6Nx/r2iPbrba6pa6p+tS2ywuIHRZ/OBvSbQZB0kWvpO9XBNVFXHD3Q==}
1320 |
1321 | use-sync-external-store@1.4.0:
1322 | resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
1323 | peerDependencies:
1324 | react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1325 |
1326 | uuid@11.1.0:
1327 | resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
1328 | hasBin: true
1329 |
1330 | which@4.0.0:
1331 | resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
1332 | engines: {node: ^16.13.0 || >=18.0.0}
1333 | hasBin: true
1334 |
1335 | workerd@1.20250310.0:
1336 | resolution: {integrity: sha512-bAaZ9Bmts3mArbIrXYAtr+ZRsAJAAUEsCtvwfBavIYXaZ5sgdEOJBEiBbvsHp6CsVObegOM85tIWpYLpbTxQrQ==}
1337 | engines: {node: '>=16'}
1338 | hasBin: true
1339 |
1340 | wrangler@4.0.0:
1341 | resolution: {integrity: sha512-9QqqoznS5sfLNqPKPkeEkwPAIe4lPfWLzPxVATmAbMQl4sh3/8iKEYSjZXQxdtcTgiS8iGOUbHq/rdiOFU8H1w==}
1342 | engines: {node: '>=18.0.0'}
1343 | hasBin: true
1344 | peerDependencies:
1345 | '@cloudflare/workers-types': ^4.20250310.0
1346 | peerDependenciesMeta:
1347 | '@cloudflare/workers-types':
1348 | optional: true
1349 |
1350 | ws@8.18.0:
1351 | resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
1352 | engines: {node: '>=10.0.0'}
1353 | peerDependencies:
1354 | bufferutil: ^4.0.1
1355 | utf-8-validate: '>=5.0.2'
1356 | peerDependenciesMeta:
1357 | bufferutil:
1358 | optional: true
1359 | utf-8-validate:
1360 | optional: true
1361 |
1362 | xtend@4.0.2:
1363 | resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
1364 | engines: {node: '>=0.4'}
1365 |
1366 | youch@3.2.3:
1367 | resolution: {integrity: sha512-ZBcWz/uzZaQVdCvfV4uk616Bbpf2ee+F/AvuKDR5EwX/Y4v06xWdtMluqTD7+KlZdM93lLm9gMZYo0sKBS0pgw==}
1368 |
1369 | zod-to-json-schema@3.24.4:
1370 | resolution: {integrity: sha512-0uNlcvgabyrni9Ag8Vghj21drk7+7tp7VTwwR7KxxXXc/3pbXz2PHlDgj3cICahgF1kHm4dExBFj7BXrZJXzig==}
1371 | peerDependencies:
1372 | zod: ^3.24.1
1373 |
1374 | zod@3.22.3:
1375 | resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==}
1376 |
1377 | zod@3.24.2:
1378 | resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==}
1379 |
1380 | snapshots:
1381 |
1382 | '@ai-sdk/openai@1.2.5(zod@3.24.2)':
1383 | dependencies:
1384 | '@ai-sdk/provider': 1.0.11
1385 | '@ai-sdk/provider-utils': 2.1.13(zod@3.24.2)
1386 | zod: 3.24.2
1387 |
1388 | '@ai-sdk/provider-utils@2.1.13(zod@3.24.2)':
1389 | dependencies:
1390 | '@ai-sdk/provider': 1.0.11
1391 | eventsource-parser: 3.0.0
1392 | nanoid: 3.3.10
1393 | secure-json-parse: 2.7.0
1394 | optionalDependencies:
1395 | zod: 3.24.2
1396 |
1397 | '@ai-sdk/provider@1.0.11':
1398 | dependencies:
1399 | json-schema: 0.4.0
1400 |
1401 | '@ai-sdk/react@1.1.23(react@19.0.0)(zod@3.24.2)':
1402 | dependencies:
1403 | '@ai-sdk/provider-utils': 2.1.13(zod@3.24.2)
1404 | '@ai-sdk/ui-utils': 1.1.19(zod@3.24.2)
1405 | swr: 2.3.3(react@19.0.0)
1406 | throttleit: 2.1.0
1407 | optionalDependencies:
1408 | react: 19.0.0
1409 | zod: 3.24.2
1410 |
1411 | '@ai-sdk/ui-utils@1.1.19(zod@3.24.2)':
1412 | dependencies:
1413 | '@ai-sdk/provider': 1.0.11
1414 | '@ai-sdk/provider-utils': 2.1.13(zod@3.24.2)
1415 | zod-to-json-schema: 3.24.4(zod@3.24.2)
1416 | optionalDependencies:
1417 | zod: 3.24.2
1418 |
1419 | '@cloudflare/kv-asset-handler@0.4.0':
1420 | dependencies:
1421 | mime: 3.0.0
1422 |
1423 | '@cloudflare/unenv-preset@2.0.2(unenv@2.0.0-rc.14)(workerd@1.20250310.0)':
1424 | dependencies:
1425 | unenv: 2.0.0-rc.14
1426 | optionalDependencies:
1427 | workerd: 1.20250310.0
1428 |
1429 | '@cloudflare/workerd-darwin-64@1.20250310.0':
1430 | optional: true
1431 |
1432 | '@cloudflare/workerd-darwin-arm64@1.20250310.0':
1433 | optional: true
1434 |
1435 | '@cloudflare/workerd-linux-64@1.20250310.0':
1436 | optional: true
1437 |
1438 | '@cloudflare/workerd-linux-arm64@1.20250310.0':
1439 | optional: true
1440 |
1441 | '@cloudflare/workerd-windows-64@1.20250310.0':
1442 | optional: true
1443 |
1444 | '@cloudflare/workers-types@4.20250313.0': {}
1445 |
1446 | '@cspotcode/source-map-support@0.8.1':
1447 | dependencies:
1448 | '@jridgewell/trace-mapping': 0.3.9
1449 |
1450 | '@drizzle-team/brocli@0.10.2': {}
1451 |
1452 | '@electric-sql/client@1.0.0-beta.5':
1453 | optionalDependencies:
1454 | '@rollup/rollup-darwin-arm64': 4.35.0
1455 |
1456 | '@emnapi/runtime@1.3.1':
1457 | dependencies:
1458 | tslib: 2.8.1
1459 | optional: true
1460 |
1461 | '@esbuild-kit/core-utils@3.3.2':
1462 | dependencies:
1463 | esbuild: 0.18.20
1464 | source-map-support: 0.5.21
1465 |
1466 | '@esbuild-kit/esm-loader@2.6.5':
1467 | dependencies:
1468 | '@esbuild-kit/core-utils': 3.3.2
1469 | get-tsconfig: 4.10.0
1470 |
1471 | '@esbuild/aix-ppc64@0.19.12':
1472 | optional: true
1473 |
1474 | '@esbuild/aix-ppc64@0.24.2':
1475 | optional: true
1476 |
1477 | '@esbuild/aix-ppc64@0.25.1':
1478 | optional: true
1479 |
1480 | '@esbuild/android-arm64@0.18.20':
1481 | optional: true
1482 |
1483 | '@esbuild/android-arm64@0.19.12':
1484 | optional: true
1485 |
1486 | '@esbuild/android-arm64@0.24.2':
1487 | optional: true
1488 |
1489 | '@esbuild/android-arm64@0.25.1':
1490 | optional: true
1491 |
1492 | '@esbuild/android-arm@0.18.20':
1493 | optional: true
1494 |
1495 | '@esbuild/android-arm@0.19.12':
1496 | optional: true
1497 |
1498 | '@esbuild/android-arm@0.24.2':
1499 | optional: true
1500 |
1501 | '@esbuild/android-arm@0.25.1':
1502 | optional: true
1503 |
1504 | '@esbuild/android-x64@0.18.20':
1505 | optional: true
1506 |
1507 | '@esbuild/android-x64@0.19.12':
1508 | optional: true
1509 |
1510 | '@esbuild/android-x64@0.24.2':
1511 | optional: true
1512 |
1513 | '@esbuild/android-x64@0.25.1':
1514 | optional: true
1515 |
1516 | '@esbuild/darwin-arm64@0.18.20':
1517 | optional: true
1518 |
1519 | '@esbuild/darwin-arm64@0.19.12':
1520 | optional: true
1521 |
1522 | '@esbuild/darwin-arm64@0.24.2':
1523 | optional: true
1524 |
1525 | '@esbuild/darwin-arm64@0.25.1':
1526 | optional: true
1527 |
1528 | '@esbuild/darwin-x64@0.18.20':
1529 | optional: true
1530 |
1531 | '@esbuild/darwin-x64@0.19.12':
1532 | optional: true
1533 |
1534 | '@esbuild/darwin-x64@0.24.2':
1535 | optional: true
1536 |
1537 | '@esbuild/darwin-x64@0.25.1':
1538 | optional: true
1539 |
1540 | '@esbuild/freebsd-arm64@0.18.20':
1541 | optional: true
1542 |
1543 | '@esbuild/freebsd-arm64@0.19.12':
1544 | optional: true
1545 |
1546 | '@esbuild/freebsd-arm64@0.24.2':
1547 | optional: true
1548 |
1549 | '@esbuild/freebsd-arm64@0.25.1':
1550 | optional: true
1551 |
1552 | '@esbuild/freebsd-x64@0.18.20':
1553 | optional: true
1554 |
1555 | '@esbuild/freebsd-x64@0.19.12':
1556 | optional: true
1557 |
1558 | '@esbuild/freebsd-x64@0.24.2':
1559 | optional: true
1560 |
1561 | '@esbuild/freebsd-x64@0.25.1':
1562 | optional: true
1563 |
1564 | '@esbuild/linux-arm64@0.18.20':
1565 | optional: true
1566 |
1567 | '@esbuild/linux-arm64@0.19.12':
1568 | optional: true
1569 |
1570 | '@esbuild/linux-arm64@0.24.2':
1571 | optional: true
1572 |
1573 | '@esbuild/linux-arm64@0.25.1':
1574 | optional: true
1575 |
1576 | '@esbuild/linux-arm@0.18.20':
1577 | optional: true
1578 |
1579 | '@esbuild/linux-arm@0.19.12':
1580 | optional: true
1581 |
1582 | '@esbuild/linux-arm@0.24.2':
1583 | optional: true
1584 |
1585 | '@esbuild/linux-arm@0.25.1':
1586 | optional: true
1587 |
1588 | '@esbuild/linux-ia32@0.18.20':
1589 | optional: true
1590 |
1591 | '@esbuild/linux-ia32@0.19.12':
1592 | optional: true
1593 |
1594 | '@esbuild/linux-ia32@0.24.2':
1595 | optional: true
1596 |
1597 | '@esbuild/linux-ia32@0.25.1':
1598 | optional: true
1599 |
1600 | '@esbuild/linux-loong64@0.18.20':
1601 | optional: true
1602 |
1603 | '@esbuild/linux-loong64@0.19.12':
1604 | optional: true
1605 |
1606 | '@esbuild/linux-loong64@0.24.2':
1607 | optional: true
1608 |
1609 | '@esbuild/linux-loong64@0.25.1':
1610 | optional: true
1611 |
1612 | '@esbuild/linux-mips64el@0.18.20':
1613 | optional: true
1614 |
1615 | '@esbuild/linux-mips64el@0.19.12':
1616 | optional: true
1617 |
1618 | '@esbuild/linux-mips64el@0.24.2':
1619 | optional: true
1620 |
1621 | '@esbuild/linux-mips64el@0.25.1':
1622 | optional: true
1623 |
1624 | '@esbuild/linux-ppc64@0.18.20':
1625 | optional: true
1626 |
1627 | '@esbuild/linux-ppc64@0.19.12':
1628 | optional: true
1629 |
1630 | '@esbuild/linux-ppc64@0.24.2':
1631 | optional: true
1632 |
1633 | '@esbuild/linux-ppc64@0.25.1':
1634 | optional: true
1635 |
1636 | '@esbuild/linux-riscv64@0.18.20':
1637 | optional: true
1638 |
1639 | '@esbuild/linux-riscv64@0.19.12':
1640 | optional: true
1641 |
1642 | '@esbuild/linux-riscv64@0.24.2':
1643 | optional: true
1644 |
1645 | '@esbuild/linux-riscv64@0.25.1':
1646 | optional: true
1647 |
1648 | '@esbuild/linux-s390x@0.18.20':
1649 | optional: true
1650 |
1651 | '@esbuild/linux-s390x@0.19.12':
1652 | optional: true
1653 |
1654 | '@esbuild/linux-s390x@0.24.2':
1655 | optional: true
1656 |
1657 | '@esbuild/linux-s390x@0.25.1':
1658 | optional: true
1659 |
1660 | '@esbuild/linux-x64@0.18.20':
1661 | optional: true
1662 |
1663 | '@esbuild/linux-x64@0.19.12':
1664 | optional: true
1665 |
1666 | '@esbuild/linux-x64@0.24.2':
1667 | optional: true
1668 |
1669 | '@esbuild/linux-x64@0.25.1':
1670 | optional: true
1671 |
1672 | '@esbuild/netbsd-arm64@0.24.2':
1673 | optional: true
1674 |
1675 | '@esbuild/netbsd-arm64@0.25.1':
1676 | optional: true
1677 |
1678 | '@esbuild/netbsd-x64@0.18.20':
1679 | optional: true
1680 |
1681 | '@esbuild/netbsd-x64@0.19.12':
1682 | optional: true
1683 |
1684 | '@esbuild/netbsd-x64@0.24.2':
1685 | optional: true
1686 |
1687 | '@esbuild/netbsd-x64@0.25.1':
1688 | optional: true
1689 |
1690 | '@esbuild/openbsd-arm64@0.24.2':
1691 | optional: true
1692 |
1693 | '@esbuild/openbsd-arm64@0.25.1':
1694 | optional: true
1695 |
1696 | '@esbuild/openbsd-x64@0.18.20':
1697 | optional: true
1698 |
1699 | '@esbuild/openbsd-x64@0.19.12':
1700 | optional: true
1701 |
1702 | '@esbuild/openbsd-x64@0.24.2':
1703 | optional: true
1704 |
1705 | '@esbuild/openbsd-x64@0.25.1':
1706 | optional: true
1707 |
1708 | '@esbuild/sunos-x64@0.18.20':
1709 | optional: true
1710 |
1711 | '@esbuild/sunos-x64@0.19.12':
1712 | optional: true
1713 |
1714 | '@esbuild/sunos-x64@0.24.2':
1715 | optional: true
1716 |
1717 | '@esbuild/sunos-x64@0.25.1':
1718 | optional: true
1719 |
1720 | '@esbuild/win32-arm64@0.18.20':
1721 | optional: true
1722 |
1723 | '@esbuild/win32-arm64@0.19.12':
1724 | optional: true
1725 |
1726 | '@esbuild/win32-arm64@0.24.2':
1727 | optional: true
1728 |
1729 | '@esbuild/win32-arm64@0.25.1':
1730 | optional: true
1731 |
1732 | '@esbuild/win32-ia32@0.18.20':
1733 | optional: true
1734 |
1735 | '@esbuild/win32-ia32@0.19.12':
1736 | optional: true
1737 |
1738 | '@esbuild/win32-ia32@0.24.2':
1739 | optional: true
1740 |
1741 | '@esbuild/win32-ia32@0.25.1':
1742 | optional: true
1743 |
1744 | '@esbuild/win32-x64@0.18.20':
1745 | optional: true
1746 |
1747 | '@esbuild/win32-x64@0.19.12':
1748 | optional: true
1749 |
1750 | '@esbuild/win32-x64@0.24.2':
1751 | optional: true
1752 |
1753 | '@esbuild/win32-x64@0.25.1':
1754 | optional: true
1755 |
1756 | '@fastify/busboy@2.1.1': {}
1757 |
1758 | '@img/sharp-darwin-arm64@0.33.5':
1759 | optionalDependencies:
1760 | '@img/sharp-libvips-darwin-arm64': 1.0.4
1761 | optional: true
1762 |
1763 | '@img/sharp-darwin-x64@0.33.5':
1764 | optionalDependencies:
1765 | '@img/sharp-libvips-darwin-x64': 1.0.4
1766 | optional: true
1767 |
1768 | '@img/sharp-libvips-darwin-arm64@1.0.4':
1769 | optional: true
1770 |
1771 | '@img/sharp-libvips-darwin-x64@1.0.4':
1772 | optional: true
1773 |
1774 | '@img/sharp-libvips-linux-arm64@1.0.4':
1775 | optional: true
1776 |
1777 | '@img/sharp-libvips-linux-arm@1.0.5':
1778 | optional: true
1779 |
1780 | '@img/sharp-libvips-linux-s390x@1.0.4':
1781 | optional: true
1782 |
1783 | '@img/sharp-libvips-linux-x64@1.0.4':
1784 | optional: true
1785 |
1786 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
1787 | optional: true
1788 |
1789 | '@img/sharp-libvips-linuxmusl-x64@1.0.4':
1790 | optional: true
1791 |
1792 | '@img/sharp-linux-arm64@0.33.5':
1793 | optionalDependencies:
1794 | '@img/sharp-libvips-linux-arm64': 1.0.4
1795 | optional: true
1796 |
1797 | '@img/sharp-linux-arm@0.33.5':
1798 | optionalDependencies:
1799 | '@img/sharp-libvips-linux-arm': 1.0.5
1800 | optional: true
1801 |
1802 | '@img/sharp-linux-s390x@0.33.5':
1803 | optionalDependencies:
1804 | '@img/sharp-libvips-linux-s390x': 1.0.4
1805 | optional: true
1806 |
1807 | '@img/sharp-linux-x64@0.33.5':
1808 | optionalDependencies:
1809 | '@img/sharp-libvips-linux-x64': 1.0.4
1810 | optional: true
1811 |
1812 | '@img/sharp-linuxmusl-arm64@0.33.5':
1813 | optionalDependencies:
1814 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
1815 | optional: true
1816 |
1817 | '@img/sharp-linuxmusl-x64@0.33.5':
1818 | optionalDependencies:
1819 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4
1820 | optional: true
1821 |
1822 | '@img/sharp-wasm32@0.33.5':
1823 | dependencies:
1824 | '@emnapi/runtime': 1.3.1
1825 | optional: true
1826 |
1827 | '@img/sharp-win32-ia32@0.33.5':
1828 | optional: true
1829 |
1830 | '@img/sharp-win32-x64@0.33.5':
1831 | optional: true
1832 |
1833 | '@jridgewell/resolve-uri@3.1.2': {}
1834 |
1835 | '@jridgewell/sourcemap-codec@1.5.0': {}
1836 |
1837 | '@jridgewell/trace-mapping@0.3.9':
1838 | dependencies:
1839 | '@jridgewell/resolve-uri': 3.1.2
1840 | '@jridgewell/sourcemap-codec': 1.5.0
1841 |
1842 | '@opentelemetry/api@1.9.0': {}
1843 |
1844 | '@petamoriken/float16@3.9.2': {}
1845 |
1846 | '@rollup/rollup-darwin-arm64@4.35.0':
1847 | optional: true
1848 |
1849 | '@types/diff-match-patch@1.0.36': {}
1850 |
1851 | '@types/node@22.13.10':
1852 | dependencies:
1853 | undici-types: 6.20.0
1854 |
1855 | '@types/pg@8.11.11':
1856 | dependencies:
1857 | '@types/node': 22.13.10
1858 | pg-protocol: 1.8.0
1859 | pg-types: 4.0.2
1860 |
1861 | '@types/uuid@10.0.0': {}
1862 |
1863 | acorn-walk@8.3.2: {}
1864 |
1865 | acorn@8.14.0: {}
1866 |
1867 | ai@4.1.61(react@19.0.0)(zod@3.24.2):
1868 | dependencies:
1869 | '@ai-sdk/provider': 1.0.11
1870 | '@ai-sdk/provider-utils': 2.1.13(zod@3.24.2)
1871 | '@ai-sdk/react': 1.1.23(react@19.0.0)(zod@3.24.2)
1872 | '@ai-sdk/ui-utils': 1.1.19(zod@3.24.2)
1873 | '@opentelemetry/api': 1.9.0
1874 | eventsource-parser: 3.0.0
1875 | jsondiffpatch: 0.6.0
1876 | optionalDependencies:
1877 | react: 19.0.0
1878 | zod: 3.24.2
1879 |
1880 | as-table@1.0.55:
1881 | dependencies:
1882 | printable-characters: 1.0.42
1883 |
1884 | blake3-wasm@2.1.5: {}
1885 |
1886 | buffer-from@1.1.2: {}
1887 |
1888 | chalk@5.4.1: {}
1889 |
1890 | color-convert@2.0.1:
1891 | dependencies:
1892 | color-name: 1.1.4
1893 | optional: true
1894 |
1895 | color-name@1.1.4:
1896 | optional: true
1897 |
1898 | color-string@1.9.1:
1899 | dependencies:
1900 | color-name: 1.1.4
1901 | simple-swizzle: 0.2.2
1902 | optional: true
1903 |
1904 | color@4.2.3:
1905 | dependencies:
1906 | color-convert: 2.0.1
1907 | color-string: 1.9.1
1908 | optional: true
1909 |
1910 | cookie@0.5.0: {}
1911 |
1912 | data-uri-to-buffer@2.0.2: {}
1913 |
1914 | debug@4.4.0:
1915 | dependencies:
1916 | ms: 2.1.3
1917 |
1918 | defu@6.1.4: {}
1919 |
1920 | dequal@2.0.3: {}
1921 |
1922 | detect-libc@2.0.3:
1923 | optional: true
1924 |
1925 | diff-match-patch@1.0.5: {}
1926 |
1927 | dotenv@16.4.7: {}
1928 |
1929 | drizzle-kit@0.30.5:
1930 | dependencies:
1931 | '@drizzle-team/brocli': 0.10.2
1932 | '@esbuild-kit/esm-loader': 2.6.5
1933 | esbuild: 0.19.12
1934 | esbuild-register: 3.6.0(esbuild@0.19.12)
1935 | gel: 2.0.1
1936 | transitivePeerDependencies:
1937 | - supports-color
1938 |
1939 | drizzle-orm@0.40.0(@cloudflare/workers-types@4.20250313.0)(@opentelemetry/api@1.9.0)(@types/pg@8.11.11)(gel@2.0.1)(pg@8.14.0):
1940 | optionalDependencies:
1941 | '@cloudflare/workers-types': 4.20250313.0
1942 | '@opentelemetry/api': 1.9.0
1943 | '@types/pg': 8.11.11
1944 | gel: 2.0.1
1945 | pg: 8.14.0
1946 |
1947 | env-paths@3.0.0: {}
1948 |
1949 | esbuild-register@3.6.0(esbuild@0.19.12):
1950 | dependencies:
1951 | debug: 4.4.0
1952 | esbuild: 0.19.12
1953 | transitivePeerDependencies:
1954 | - supports-color
1955 |
1956 | esbuild@0.18.20:
1957 | optionalDependencies:
1958 | '@esbuild/android-arm': 0.18.20
1959 | '@esbuild/android-arm64': 0.18.20
1960 | '@esbuild/android-x64': 0.18.20
1961 | '@esbuild/darwin-arm64': 0.18.20
1962 | '@esbuild/darwin-x64': 0.18.20
1963 | '@esbuild/freebsd-arm64': 0.18.20
1964 | '@esbuild/freebsd-x64': 0.18.20
1965 | '@esbuild/linux-arm': 0.18.20
1966 | '@esbuild/linux-arm64': 0.18.20
1967 | '@esbuild/linux-ia32': 0.18.20
1968 | '@esbuild/linux-loong64': 0.18.20
1969 | '@esbuild/linux-mips64el': 0.18.20
1970 | '@esbuild/linux-ppc64': 0.18.20
1971 | '@esbuild/linux-riscv64': 0.18.20
1972 | '@esbuild/linux-s390x': 0.18.20
1973 | '@esbuild/linux-x64': 0.18.20
1974 | '@esbuild/netbsd-x64': 0.18.20
1975 | '@esbuild/openbsd-x64': 0.18.20
1976 | '@esbuild/sunos-x64': 0.18.20
1977 | '@esbuild/win32-arm64': 0.18.20
1978 | '@esbuild/win32-ia32': 0.18.20
1979 | '@esbuild/win32-x64': 0.18.20
1980 |
1981 | esbuild@0.19.12:
1982 | optionalDependencies:
1983 | '@esbuild/aix-ppc64': 0.19.12
1984 | '@esbuild/android-arm': 0.19.12
1985 | '@esbuild/android-arm64': 0.19.12
1986 | '@esbuild/android-x64': 0.19.12
1987 | '@esbuild/darwin-arm64': 0.19.12
1988 | '@esbuild/darwin-x64': 0.19.12
1989 | '@esbuild/freebsd-arm64': 0.19.12
1990 | '@esbuild/freebsd-x64': 0.19.12
1991 | '@esbuild/linux-arm': 0.19.12
1992 | '@esbuild/linux-arm64': 0.19.12
1993 | '@esbuild/linux-ia32': 0.19.12
1994 | '@esbuild/linux-loong64': 0.19.12
1995 | '@esbuild/linux-mips64el': 0.19.12
1996 | '@esbuild/linux-ppc64': 0.19.12
1997 | '@esbuild/linux-riscv64': 0.19.12
1998 | '@esbuild/linux-s390x': 0.19.12
1999 | '@esbuild/linux-x64': 0.19.12
2000 | '@esbuild/netbsd-x64': 0.19.12
2001 | '@esbuild/openbsd-x64': 0.19.12
2002 | '@esbuild/sunos-x64': 0.19.12
2003 | '@esbuild/win32-arm64': 0.19.12
2004 | '@esbuild/win32-ia32': 0.19.12
2005 | '@esbuild/win32-x64': 0.19.12
2006 |
2007 | esbuild@0.24.2:
2008 | optionalDependencies:
2009 | '@esbuild/aix-ppc64': 0.24.2
2010 | '@esbuild/android-arm': 0.24.2
2011 | '@esbuild/android-arm64': 0.24.2
2012 | '@esbuild/android-x64': 0.24.2
2013 | '@esbuild/darwin-arm64': 0.24.2
2014 | '@esbuild/darwin-x64': 0.24.2
2015 | '@esbuild/freebsd-arm64': 0.24.2
2016 | '@esbuild/freebsd-x64': 0.24.2
2017 | '@esbuild/linux-arm': 0.24.2
2018 | '@esbuild/linux-arm64': 0.24.2
2019 | '@esbuild/linux-ia32': 0.24.2
2020 | '@esbuild/linux-loong64': 0.24.2
2021 | '@esbuild/linux-mips64el': 0.24.2
2022 | '@esbuild/linux-ppc64': 0.24.2
2023 | '@esbuild/linux-riscv64': 0.24.2
2024 | '@esbuild/linux-s390x': 0.24.2
2025 | '@esbuild/linux-x64': 0.24.2
2026 | '@esbuild/netbsd-arm64': 0.24.2
2027 | '@esbuild/netbsd-x64': 0.24.2
2028 | '@esbuild/openbsd-arm64': 0.24.2
2029 | '@esbuild/openbsd-x64': 0.24.2
2030 | '@esbuild/sunos-x64': 0.24.2
2031 | '@esbuild/win32-arm64': 0.24.2
2032 | '@esbuild/win32-ia32': 0.24.2
2033 | '@esbuild/win32-x64': 0.24.2
2034 |
2035 | esbuild@0.25.1:
2036 | optionalDependencies:
2037 | '@esbuild/aix-ppc64': 0.25.1
2038 | '@esbuild/android-arm': 0.25.1
2039 | '@esbuild/android-arm64': 0.25.1
2040 | '@esbuild/android-x64': 0.25.1
2041 | '@esbuild/darwin-arm64': 0.25.1
2042 | '@esbuild/darwin-x64': 0.25.1
2043 | '@esbuild/freebsd-arm64': 0.25.1
2044 | '@esbuild/freebsd-x64': 0.25.1
2045 | '@esbuild/linux-arm': 0.25.1
2046 | '@esbuild/linux-arm64': 0.25.1
2047 | '@esbuild/linux-ia32': 0.25.1
2048 | '@esbuild/linux-loong64': 0.25.1
2049 | '@esbuild/linux-mips64el': 0.25.1
2050 | '@esbuild/linux-ppc64': 0.25.1
2051 | '@esbuild/linux-riscv64': 0.25.1
2052 | '@esbuild/linux-s390x': 0.25.1
2053 | '@esbuild/linux-x64': 0.25.1
2054 | '@esbuild/netbsd-arm64': 0.25.1
2055 | '@esbuild/netbsd-x64': 0.25.1
2056 | '@esbuild/openbsd-arm64': 0.25.1
2057 | '@esbuild/openbsd-x64': 0.25.1
2058 | '@esbuild/sunos-x64': 0.25.1
2059 | '@esbuild/win32-arm64': 0.25.1
2060 | '@esbuild/win32-ia32': 0.25.1
2061 | '@esbuild/win32-x64': 0.25.1
2062 |
2063 | eventsource-parser@3.0.0: {}
2064 |
2065 | exit-hook@2.2.1: {}
2066 |
2067 | exsolve@1.0.4: {}
2068 |
2069 | fsevents@2.3.3:
2070 | optional: true
2071 |
2072 | gel@2.0.1:
2073 | dependencies:
2074 | '@petamoriken/float16': 3.9.2
2075 | debug: 4.4.0
2076 | env-paths: 3.0.0
2077 | semver: 7.7.1
2078 | shell-quote: 1.8.2
2079 | which: 4.0.0
2080 | transitivePeerDependencies:
2081 | - supports-color
2082 |
2083 | get-source@2.0.12:
2084 | dependencies:
2085 | data-uri-to-buffer: 2.0.2
2086 | source-map: 0.6.1
2087 |
2088 | get-tsconfig@4.10.0:
2089 | dependencies:
2090 | resolve-pkg-maps: 1.0.0
2091 |
2092 | glob-to-regexp@0.4.1: {}
2093 |
2094 | hono@4.7.4: {}
2095 |
2096 | is-arrayish@0.3.2:
2097 | optional: true
2098 |
2099 | isexe@3.1.1: {}
2100 |
2101 | json-schema@0.4.0: {}
2102 |
2103 | jsondiffpatch@0.6.0:
2104 | dependencies:
2105 | '@types/diff-match-patch': 1.0.36
2106 | chalk: 5.4.1
2107 | diff-match-patch: 1.0.5
2108 |
2109 | mime@3.0.0: {}
2110 |
2111 | miniflare@4.20250310.0:
2112 | dependencies:
2113 | '@cspotcode/source-map-support': 0.8.1
2114 | acorn: 8.14.0
2115 | acorn-walk: 8.3.2
2116 | exit-hook: 2.2.1
2117 | glob-to-regexp: 0.4.1
2118 | stoppable: 1.1.0
2119 | undici: 5.28.5
2120 | workerd: 1.20250310.0
2121 | ws: 8.18.0
2122 | youch: 3.2.3
2123 | zod: 3.22.3
2124 | transitivePeerDependencies:
2125 | - bufferutil
2126 | - utf-8-validate
2127 |
2128 | ms@2.1.3: {}
2129 |
2130 | mustache@4.2.0: {}
2131 |
2132 | nanoid@3.3.10: {}
2133 |
2134 | obuf@1.1.2: {}
2135 |
2136 | ohash@2.0.11: {}
2137 |
2138 | path-to-regexp@6.3.0: {}
2139 |
2140 | pathe@2.0.3: {}
2141 |
2142 | pg-cloudflare@1.1.1:
2143 | optional: true
2144 |
2145 | pg-connection-string@2.7.0: {}
2146 |
2147 | pg-int8@1.0.1: {}
2148 |
2149 | pg-numeric@1.0.2: {}
2150 |
2151 | pg-pool@3.8.0(pg@8.14.0):
2152 | dependencies:
2153 | pg: 8.14.0
2154 |
2155 | pg-protocol@1.8.0: {}
2156 |
2157 | pg-types@2.2.0:
2158 | dependencies:
2159 | pg-int8: 1.0.1
2160 | postgres-array: 2.0.0
2161 | postgres-bytea: 1.0.0
2162 | postgres-date: 1.0.7
2163 | postgres-interval: 1.2.0
2164 |
2165 | pg-types@4.0.2:
2166 | dependencies:
2167 | pg-int8: 1.0.1
2168 | pg-numeric: 1.0.2
2169 | postgres-array: 3.0.4
2170 | postgres-bytea: 3.0.0
2171 | postgres-date: 2.1.0
2172 | postgres-interval: 3.0.0
2173 | postgres-range: 1.1.4
2174 |
2175 | pg@8.14.0:
2176 | dependencies:
2177 | pg-connection-string: 2.7.0
2178 | pg-pool: 3.8.0(pg@8.14.0)
2179 | pg-protocol: 1.8.0
2180 | pg-types: 2.2.0
2181 | pgpass: 1.0.5
2182 | optionalDependencies:
2183 | pg-cloudflare: 1.1.1
2184 |
2185 | pgpass@1.0.5:
2186 | dependencies:
2187 | split2: 4.2.0
2188 |
2189 | postgres-array@2.0.0: {}
2190 |
2191 | postgres-array@3.0.4: {}
2192 |
2193 | postgres-bytea@1.0.0: {}
2194 |
2195 | postgres-bytea@3.0.0:
2196 | dependencies:
2197 | obuf: 1.1.2
2198 |
2199 | postgres-date@1.0.7: {}
2200 |
2201 | postgres-date@2.1.0: {}
2202 |
2203 | postgres-interval@1.2.0:
2204 | dependencies:
2205 | xtend: 4.0.2
2206 |
2207 | postgres-interval@3.0.0: {}
2208 |
2209 | postgres-range@1.1.4: {}
2210 |
2211 | printable-characters@1.0.42: {}
2212 |
2213 | react@19.0.0: {}
2214 |
2215 | resolve-pkg-maps@1.0.0: {}
2216 |
2217 | secure-json-parse@2.7.0: {}
2218 |
2219 | semver@7.7.1: {}
2220 |
2221 | sharp@0.33.5:
2222 | dependencies:
2223 | color: 4.2.3
2224 | detect-libc: 2.0.3
2225 | semver: 7.7.1
2226 | optionalDependencies:
2227 | '@img/sharp-darwin-arm64': 0.33.5
2228 | '@img/sharp-darwin-x64': 0.33.5
2229 | '@img/sharp-libvips-darwin-arm64': 1.0.4
2230 | '@img/sharp-libvips-darwin-x64': 1.0.4
2231 | '@img/sharp-libvips-linux-arm': 1.0.5
2232 | '@img/sharp-libvips-linux-arm64': 1.0.4
2233 | '@img/sharp-libvips-linux-s390x': 1.0.4
2234 | '@img/sharp-libvips-linux-x64': 1.0.4
2235 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
2236 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4
2237 | '@img/sharp-linux-arm': 0.33.5
2238 | '@img/sharp-linux-arm64': 0.33.5
2239 | '@img/sharp-linux-s390x': 0.33.5
2240 | '@img/sharp-linux-x64': 0.33.5
2241 | '@img/sharp-linuxmusl-arm64': 0.33.5
2242 | '@img/sharp-linuxmusl-x64': 0.33.5
2243 | '@img/sharp-wasm32': 0.33.5
2244 | '@img/sharp-win32-ia32': 0.33.5
2245 | '@img/sharp-win32-x64': 0.33.5
2246 | optional: true
2247 |
2248 | shell-quote@1.8.2: {}
2249 |
2250 | simple-swizzle@0.2.2:
2251 | dependencies:
2252 | is-arrayish: 0.3.2
2253 | optional: true
2254 |
2255 | source-map-support@0.5.21:
2256 | dependencies:
2257 | buffer-from: 1.1.2
2258 | source-map: 0.6.1
2259 |
2260 | source-map@0.6.1: {}
2261 |
2262 | split2@4.2.0: {}
2263 |
2264 | stacktracey@2.1.8:
2265 | dependencies:
2266 | as-table: 1.0.55
2267 | get-source: 2.0.12
2268 |
2269 | stoppable@1.1.0: {}
2270 |
2271 | swr@2.3.3(react@19.0.0):
2272 | dependencies:
2273 | dequal: 2.0.3
2274 | react: 19.0.0
2275 | use-sync-external-store: 1.4.0(react@19.0.0)
2276 |
2277 | throttleit@2.1.0: {}
2278 |
2279 | tslib@2.8.1:
2280 | optional: true
2281 |
2282 | tsx@4.19.3:
2283 | dependencies:
2284 | esbuild: 0.25.1
2285 | get-tsconfig: 4.10.0
2286 | optionalDependencies:
2287 | fsevents: 2.3.3
2288 |
2289 | ufo@1.5.4: {}
2290 |
2291 | undici-types@6.20.0: {}
2292 |
2293 | undici@5.28.5:
2294 | dependencies:
2295 | '@fastify/busboy': 2.1.1
2296 |
2297 | unenv@2.0.0-rc.14:
2298 | dependencies:
2299 | defu: 6.1.4
2300 | exsolve: 1.0.4
2301 | ohash: 2.0.11
2302 | pathe: 2.0.3
2303 | ufo: 1.5.4
2304 |
2305 | use-sync-external-store@1.4.0(react@19.0.0):
2306 | dependencies:
2307 | react: 19.0.0
2308 |
2309 | uuid@11.1.0: {}
2310 |
2311 | which@4.0.0:
2312 | dependencies:
2313 | isexe: 3.1.1
2314 |
2315 | workerd@1.20250310.0:
2316 | optionalDependencies:
2317 | '@cloudflare/workerd-darwin-64': 1.20250310.0
2318 | '@cloudflare/workerd-darwin-arm64': 1.20250310.0
2319 | '@cloudflare/workerd-linux-64': 1.20250310.0
2320 | '@cloudflare/workerd-linux-arm64': 1.20250310.0
2321 | '@cloudflare/workerd-windows-64': 1.20250310.0
2322 |
2323 | wrangler@4.0.0(@cloudflare/workers-types@4.20250313.0):
2324 | dependencies:
2325 | '@cloudflare/kv-asset-handler': 0.4.0
2326 | '@cloudflare/unenv-preset': 2.0.2(unenv@2.0.0-rc.14)(workerd@1.20250310.0)
2327 | blake3-wasm: 2.1.5
2328 | esbuild: 0.24.2
2329 | miniflare: 4.20250310.0
2330 | path-to-regexp: 6.3.0
2331 | unenv: 2.0.0-rc.14
2332 | workerd: 1.20250310.0
2333 | optionalDependencies:
2334 | '@cloudflare/workers-types': 4.20250313.0
2335 | fsevents: 2.3.3
2336 | sharp: 0.33.5
2337 | transitivePeerDependencies:
2338 | - bufferutil
2339 | - utf-8-validate
2340 |
2341 | ws@8.18.0: {}
2342 |
2343 | xtend@4.0.2: {}
2344 |
2345 | youch@3.2.3:
2346 | dependencies:
2347 | cookie: 0.5.0
2348 | mustache: 4.2.0
2349 | stacktracey: 2.1.8
2350 |
2351 | zod-to-json-schema@3.24.4(zod@3.24.2):
2352 | dependencies:
2353 | zod: 3.24.2
2354 |
2355 | zod@3.22.3: {}
2356 |
2357 | zod@3.24.2: {}
2358 |
--------------------------------------------------------------------------------
/worker/src/db/schema.ts:
--------------------------------------------------------------------------------
1 | import { InferSelectModel } from "drizzle-orm";
2 | import {
3 | index,
4 | integer,
5 | pgTable,
6 | primaryKey,
7 | varchar,
8 | } from "drizzle-orm/pg-core";
9 |
10 | export const threadsTable = pgTable(
11 | "threads",
12 | {
13 | thread_id: varchar("thread_id", { length: 255 }).notNull(),
14 | sequence: integer("sequence").notNull(),
15 | payload: varchar("payload", { length: 65536 }).notNull(),
16 | },
17 | (table) => ({
18 | pk: primaryKey({ columns: [table.thread_id, table.sequence] }),
19 | threadIdSequenceIdx: index("threads_thread_id_sequence_idx").on(
20 | table.thread_id,
21 | table.sequence
22 | ),
23 | })
24 | );
25 |
26 | export type ThreadStreamChunksTableRow = InferSelectModel;
27 |
--------------------------------------------------------------------------------
/worker/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Hono } from "hono";
2 | import { ShapeStream } from "@electric-sql/client";
3 | import { threadsTable, ThreadStreamChunksTableRow } from "./db/schema";
4 | import { streamText } from "ai";
5 | import { createOpenAI } from "@ai-sdk/openai";
6 | import { cors } from "hono/cors";
7 | import { drizzle } from "drizzle-orm/node-postgres";
8 | import { sql } from "drizzle-orm";
9 | import { chunkByLineStream } from "./util/splitByLineStream";
10 |
11 | type Bindings = {
12 | OPENAI_API_KEY: string;
13 | DATABASE_URL: string;
14 | ELECTRIC_URL: string;
15 | };
16 |
17 | const app = new Hono<{ Bindings: Bindings }>();
18 |
19 | app.use(cors());
20 |
21 | const insertPayload = (
22 | db: ReturnType,
23 | thread_id: string,
24 | payload: unknown
25 | ) => {
26 | return db.insert(threadsTable).values({
27 | thread_id,
28 | sequence: sql`(SELECT COALESCE(MAX(sequence), -1) + 1 FROM ${threadsTable} WHERE ${threadsTable.thread_id} = ${thread_id})`,
29 | payload: JSON.stringify(payload),
30 | });
31 | };
32 |
33 | app.post("/api/chat", async (c) => {
34 | const { thread_id, messages } = await c.req.json();
35 |
36 | const userMessage = messages.at(-1);
37 | const openai = createOpenAI({
38 | apiKey: c.env.OPENAI_API_KEY,
39 | });
40 |
41 | const db = drizzle(c.env.DATABASE_URL);
42 |
43 | const result = streamText({
44 | model: openai("gpt-4o-mini"),
45 | messages,
46 | });
47 |
48 | c.executionCtx.waitUntil(
49 | result
50 | .toDataStream()
51 | .pipeThrough(new TextDecoderStream())
52 | .pipeThrough(chunkByLineStream())
53 | .pipeTo(
54 | new WritableStream({
55 | start: async () => {
56 | // append the user message
57 | await insertPayload(db, thread_id, {
58 | type: "message",
59 | message: userMessage,
60 | });
61 | },
62 | write: async (chunk) => {
63 | await insertPayload(db, thread_id, { type: "ai-chunk", chunk });
64 | },
65 | })
66 | )
67 | );
68 |
69 | return result.toDataStreamResponse();
70 | });
71 |
72 | export default app;
73 |
--------------------------------------------------------------------------------
/worker/src/util/splitByLineStream.ts:
--------------------------------------------------------------------------------
1 | export function chunkByLineStream() {
2 | let buffer = "";
3 |
4 | return new TransformStream({
5 | transform(chunk, controller) {
6 | buffer += chunk;
7 | const lines = buffer.split("\n");
8 |
9 | // Process all complete lines
10 | for (let i = 0; i < lines.length - 1; i++) {
11 | controller.enqueue(lines[i]);
12 | }
13 |
14 | // Keep the last incomplete line in the buffer
15 | buffer = lines[lines.length - 1]!;
16 | },
17 | flush(controller) {
18 | // flush any remaining content in the buffer
19 | if (buffer) {
20 | controller.enqueue(buffer);
21 | }
22 | },
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/worker/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "strict": true,
7 | "skipLibCheck": true,
8 | "lib": [
9 | "ESNext"
10 | ],
11 | "types": [
12 | "@cloudflare/workers-types/2023-07-01"
13 | ],
14 | "jsx": "react-jsx",
15 | "jsxImportSource": "hono/jsx"
16 | },
17 | }
--------------------------------------------------------------------------------
/worker/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "name": "worker",
4 | "main": "src/index.ts",
5 | "compatibility_date": "2025-03-17",
6 | "compatibility_flags": ["nodejs_compat"]
7 | // "vars": {
8 | // "MY_VAR": "my-variable"
9 | // },
10 | // "kv_namespaces": [
11 | // {
12 | // "binding": "MY_KV_NAMESPACE",
13 | // "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
14 | // }
15 | // ],
16 | // "r2_buckets": [
17 | // {
18 | // "binding": "MY_BUCKET",
19 | // "bucket_name": "my-bucket"
20 | // }
21 | // ],
22 | // "d1_databases": [
23 | // {
24 | // "binding": "MY_DB",
25 | // "database_name": "my-database",
26 | // "database_id": ""
27 | // }
28 | // ],
29 | // "ai": {
30 | // "binding": "AI"
31 | // },
32 | // "observability": {
33 | // "enabled": true,
34 | // "head_sampling_rate": 1
35 | // }
36 | }
37 |
--------------------------------------------------------------------------------