@tanstack/create 0.49.1 → 0.49.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/dist/file-helpers.js +3 -1
- package/dist/frameworks/react/add-ons/ai/assets/src/data/demo-guitars.ts +93 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/hooks/demo-useAudioRecorder.ts +85 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/hooks/demo-useTTS.ts +78 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/lib/demo-ai-hook.ts +22 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/lib/demo-guitar-tools.ts +40 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.chat.ts +99 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.image.ts +72 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.structured.ts +136 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.transcription.ts +89 -0
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.tts.ts +81 -0
- package/dist/frameworks/react/add-ons/better-auth/assets/src/lib/auth-client.ts +3 -0
- package/dist/frameworks/react/add-ons/better-auth/assets/src/lib/auth.ts +9 -0
- package/dist/frameworks/react/add-ons/better-auth/assets/src/routes/api/auth/$.ts +11 -0
- package/dist/frameworks/react/add-ons/convex/assets/convex/schema.ts +14 -0
- package/dist/frameworks/react/add-ons/convex/assets/convex/todos.ts +43 -0
- package/dist/frameworks/react/add-ons/db/assets/src/db-collections/index.ts +20 -0
- package/dist/frameworks/react/add-ons/db/assets/src/hooks/demo.useChat.ts +62 -0
- package/dist/frameworks/react/add-ons/db/assets/src/routes/demo/db-chat-api.ts +83 -0
- package/dist/frameworks/react/add-ons/form/assets/src/hooks/demo.form-context.ts +4 -0
- package/dist/frameworks/react/add-ons/form/assets/src/hooks/demo.form.ts +22 -0
- package/dist/frameworks/react/add-ons/mcp/assets/src/mcp-todos.ts +51 -0
- package/dist/frameworks/react/add-ons/mcp/assets/src/routes/demo/api.mcp-todos.ts +37 -0
- package/dist/frameworks/react/add-ons/mcp/assets/src/routes/{mcp.js → mcp.ts} +27 -17
- package/dist/frameworks/react/add-ons/mcp/assets/src/utils/mcp-handler.ts +61 -0
- package/dist/frameworks/react/add-ons/neon/assets/neon-vite-plugin.ts +10 -0
- package/dist/frameworks/react/add-ons/neon/assets/src/db.ts +13 -0
- package/dist/frameworks/react/add-ons/oRPC/assets/src/orpc/client.ts +29 -0
- package/dist/frameworks/react/add-ons/oRPC/assets/src/orpc/router/index.ts +6 -0
- package/dist/frameworks/react/add-ons/oRPC/assets/src/orpc/router/todos.ts +20 -0
- package/dist/frameworks/react/add-ons/oRPC/assets/src/orpc/schema.ts +6 -0
- package/dist/frameworks/react/add-ons/oRPC/assets/src/{polyfill.js → polyfill.ts} +4 -1
- package/dist/frameworks/react/add-ons/oRPC/assets/src/routes/api.$.ts +77 -0
- package/dist/frameworks/react/add-ons/oRPC/assets/src/routes/api.rpc.$.ts +29 -0
- package/dist/frameworks/react/add-ons/shadcn/assets/src/lib/utils.ts +6 -0
- package/dist/frameworks/react/add-ons/start/assets/src/data/demo.punk-songs.ts +13 -0
- package/dist/frameworks/react/add-ons/start/assets/src/routes/demo/api.names.ts +10 -0
- package/dist/frameworks/react/add-ons/store/assets/src/lib/demo-store.ts +13 -0
- package/dist/frameworks/react/add-ons/storybook/assets/_dot_storybook/main.ts +17 -0
- package/dist/frameworks/react/add-ons/storybook/assets/_dot_storybook/preview.ts +15 -0
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.stories.ts +67 -0
- package/dist/{types/frameworks/react/add-ons/storybook/assets/src/components/storybook/index.d.ts → frameworks/react/add-ons/storybook/assets/src/components/storybook/index.ts} +4 -0
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.stories.ts +43 -0
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.stories.ts +53 -0
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.stories.ts +55 -0
- package/dist/frameworks/{solid/add-ons/strapi/assets/src/lib/strapiClient.js → react/add-ons/strapi/assets/src/lib/strapiClient.ts} +3 -1
- package/dist/frameworks/react/add-ons/t3env/assets/src/env.ts +39 -0
- package/dist/frameworks/react/add-ons/tRPC/assets/src/integrations/trpc/{init.js → init.ts} +3 -1
- package/dist/frameworks/react/add-ons/tRPC/assets/src/integrations/trpc/react.ts +4 -0
- package/dist/frameworks/react/add-ons/tRPC/assets/src/integrations/trpc/router.ts +27 -0
- package/dist/frameworks/react/add-ons/table/assets/src/data/demo-table-data.ts +50 -0
- package/dist/frameworks/react/examples/events/assets/content-collections.ts +56 -0
- package/dist/frameworks/react/examples/events/assets/src/lib/conference-ai-hook.ts +26 -0
- package/dist/frameworks/react/examples/events/assets/src/lib/conference-tools.ts +210 -0
- package/dist/frameworks/react/examples/events/assets/src/lib/utils.ts +6 -0
- package/dist/frameworks/react/examples/events/assets/src/routes/api.remy-chat.ts +121 -0
- package/dist/frameworks/react/examples/resume/assets/content-collections.ts +36 -0
- package/dist/frameworks/react/examples/resume/assets/src/lib/resume-ai-hook.ts +21 -0
- package/dist/frameworks/react/examples/resume/assets/src/lib/resume-tools.ts +165 -0
- package/dist/frameworks/react/examples/resume/assets/src/lib/utils.ts +6 -0
- package/dist/frameworks/react/examples/resume/assets/src/routes/api.resume-chat.ts +110 -0
- package/dist/frameworks/solid/add-ons/better-auth/assets/src/lib/auth-client.ts +3 -0
- package/dist/frameworks/solid/add-ons/better-auth/assets/src/lib/auth.ts +9 -0
- package/dist/frameworks/solid/add-ons/better-auth/assets/src/routes/api/auth/$.ts +11 -0
- package/dist/frameworks/solid/add-ons/convex/assets/convex/schema.ts +14 -0
- package/dist/frameworks/solid/add-ons/convex/assets/convex/todos.ts +43 -0
- package/dist/frameworks/solid/add-ons/solid-ui/assets/src/lib/utils.ts +6 -0
- package/dist/frameworks/solid/add-ons/store/assets/src/lib/demo-store.ts +13 -0
- package/dist/frameworks/{react/add-ons/strapi/assets/src/lib/strapiClient.js → solid/add-ons/strapi/assets/src/lib/strapiClient.ts} +3 -1
- package/dist/frameworks/solid/add-ons/t3env/assets/src/env.ts +39 -0
- package/dist/frameworks/solid/examples/tanchat/assets/ai-streaming-server/src/index.ts +102 -0
- package/dist/frameworks/solid/examples/tanchat/assets/src/lib/demo-store.ts +13 -0
- package/dist/frameworks/solid/examples/tanchat/assets/src/store/demo.hooks.ts +17 -0
- package/dist/frameworks/solid/examples/tanchat/assets/src/store/demo.store.ts +133 -0
- package/dist/special-steps/post-init-script.js +6 -6
- package/package.json +11 -12
- package/src/file-helpers.ts +4 -1
- package/src/special-steps/post-init-script.ts +6 -6
- package/tests/copy-assets.test.ts +53 -0
- package/tests/file-helper.test.ts +19 -0
- package/tests/special-steps.test.ts +12 -12
- package/dist/frameworks/react/add-ons/ai/assets/src/data/demo-guitars.js +0 -67
- package/dist/frameworks/react/add-ons/ai/assets/src/hooks/demo-useAudioRecorder.js +0 -70
- package/dist/frameworks/react/add-ons/ai/assets/src/hooks/demo-useTTS.js +0 -66
- package/dist/frameworks/react/add-ons/ai/assets/src/lib/demo-ai-hook.js +0 -11
- package/dist/frameworks/react/add-ons/ai/assets/src/lib/demo-guitar-tools.js +0 -32
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.chat.js +0 -87
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.image.js +0 -55
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.structured.js +0 -116
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.transcription.js +0 -73
- package/dist/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.tts.js +0 -58
- package/dist/frameworks/react/add-ons/better-auth/assets/src/lib/auth-client.js +0 -2
- package/dist/frameworks/react/add-ons/better-auth/assets/src/lib/auth.js +0 -8
- package/dist/frameworks/react/add-ons/better-auth/assets/src/routes/api/auth/$.js +0 -10
- package/dist/frameworks/react/add-ons/convex/assets/convex/schema.js +0 -13
- package/dist/frameworks/react/add-ons/convex/assets/convex/todos.js +0 -39
- package/dist/frameworks/react/add-ons/db/assets/src/db-collections/index.js +0 -11
- package/dist/frameworks/react/add-ons/db/assets/src/hooks/demo.useChat.js +0 -47
- package/dist/frameworks/react/add-ons/db/assets/src/routes/demo/db-chat-api.js +0 -68
- package/dist/frameworks/react/add-ons/form/assets/src/hooks/demo.form-context.js +0 -2
- package/dist/frameworks/react/add-ons/form/assets/src/hooks/demo.form.js +0 -15
- package/dist/frameworks/react/add-ons/mcp/assets/src/mcp-todos.js +0 -40
- package/dist/frameworks/react/add-ons/mcp/assets/src/routes/demo/api.mcp-todos.js +0 -36
- package/dist/frameworks/react/add-ons/mcp/assets/src/utils/mcp-handler.js +0 -41
- package/dist/frameworks/react/add-ons/neon/assets/neon-vite-plugin.js +0 -9
- package/dist/frameworks/react/add-ons/neon/assets/src/db.js +0 -11
- package/dist/frameworks/react/add-ons/oRPC/assets/src/orpc/client.js +0 -21
- package/dist/frameworks/react/add-ons/oRPC/assets/src/orpc/router/index.js +0 -5
- package/dist/frameworks/react/add-ons/oRPC/assets/src/orpc/router/todos.js +0 -17
- package/dist/frameworks/react/add-ons/oRPC/assets/src/orpc/schema.js +0 -5
- package/dist/frameworks/react/add-ons/oRPC/assets/src/routes/api.$.js +0 -71
- package/dist/frameworks/react/add-ons/oRPC/assets/src/routes/api.rpc.$.js +0 -24
- package/dist/frameworks/react/add-ons/shadcn/assets/src/lib/utils.js +0 -5
- package/dist/frameworks/react/add-ons/start/assets/src/data/demo.punk-songs.js +0 -12
- package/dist/frameworks/react/add-ons/start/assets/src/routes/demo/api.names.js +0 -9
- package/dist/frameworks/react/add-ons/store/assets/src/lib/demo-store.js +0 -10
- package/dist/frameworks/react/add-ons/storybook/assets/_dot_storybook/main.js +0 -15
- package/dist/frameworks/react/add-ons/storybook/assets/_dot_storybook/preview.js +0 -12
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.stories.js +0 -55
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/index.js +0 -5
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.stories.js +0 -35
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.stories.js +0 -45
- package/dist/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.stories.js +0 -46
- package/dist/frameworks/react/add-ons/t3env/assets/src/env.js +0 -34
- package/dist/frameworks/react/add-ons/tRPC/assets/src/integrations/trpc/react.js +0 -2
- package/dist/frameworks/react/add-ons/tRPC/assets/src/integrations/trpc/router.js +0 -20
- package/dist/frameworks/react/add-ons/table/assets/src/data/demo-table-data.js +0 -35
- package/dist/frameworks/react/examples/events/assets/content-collections.js +0 -53
- package/dist/frameworks/react/examples/events/assets/src/lib/conference-ai-hook.js +0 -16
- package/dist/frameworks/react/examples/events/assets/src/lib/conference-tools.js +0 -177
- package/dist/frameworks/react/examples/events/assets/src/lib/utils.js +0 -5
- package/dist/frameworks/react/examples/events/assets/src/routes/api.remy-chat.js +0 -103
- package/dist/frameworks/react/examples/resume/assets/content-collections.js +0 -33
- package/dist/frameworks/react/examples/resume/assets/src/lib/resume-ai-hook.js +0 -11
- package/dist/frameworks/react/examples/resume/assets/src/lib/resume-tools.js +0 -135
- package/dist/frameworks/react/examples/resume/assets/src/lib/utils.js +0 -5
- package/dist/frameworks/react/examples/resume/assets/src/routes/api.resume-chat.js +0 -92
- package/dist/frameworks/solid/add-ons/better-auth/assets/src/lib/auth-client.js +0 -2
- package/dist/frameworks/solid/add-ons/better-auth/assets/src/lib/auth.js +0 -8
- package/dist/frameworks/solid/add-ons/better-auth/assets/src/routes/api/auth/$.js +0 -10
- package/dist/frameworks/solid/add-ons/convex/assets/convex/schema.js +0 -13
- package/dist/frameworks/solid/add-ons/convex/assets/convex/todos.js +0 -39
- package/dist/frameworks/solid/add-ons/solid-ui/assets/src/lib/utils.js +0 -5
- package/dist/frameworks/solid/add-ons/store/assets/src/lib/demo-store.js +0 -10
- package/dist/frameworks/solid/add-ons/t3env/assets/src/env.js +0 -34
- package/dist/frameworks/solid/examples/tanchat/assets/ai-streaming-server/src/index.js +0 -73
- package/dist/frameworks/solid/examples/tanchat/assets/src/lib/demo-store.js +0 -10
- package/dist/frameworks/solid/examples/tanchat/assets/src/store/demo.hooks.js +0 -12
- package/dist/frameworks/solid/examples/tanchat/assets/src/store/demo.store.js +0 -92
- package/dist/types/frameworks/react/add-ons/ai/assets/src/data/demo-guitars.d.ts +0 -10
- package/dist/types/frameworks/react/add-ons/ai/assets/src/hooks/demo-useAudioRecorder.d.ts +0 -9
- package/dist/types/frameworks/react/add-ons/ai/assets/src/hooks/demo-useTTS.d.ts +0 -8
- package/dist/types/frameworks/react/add-ons/ai/assets/src/lib/demo-ai-hook.d.ts +0 -5
- package/dist/types/frameworks/react/add-ons/ai/assets/src/lib/demo-guitar-tools.d.ts +0 -3
- package/dist/types/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.chat.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.image.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.structured.d.ts +0 -83
- package/dist/types/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.transcription.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/ai/assets/src/routes/demo/api.ai.tts.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/better-auth/assets/src/lib/auth-client.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/better-auth/assets/src/lib/auth.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/better-auth/assets/src/routes/api/auth/$.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/convex/assets/convex/schema.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/convex/assets/convex/todos.d.ts +0 -4
- package/dist/types/frameworks/react/add-ons/db/assets/src/db-collections/index.d.ts +0 -17
- package/dist/types/frameworks/react/add-ons/db/assets/src/hooks/demo.useChat.d.ts +0 -5
- package/dist/types/frameworks/react/add-ons/db/assets/src/routes/demo/db-chat-api.d.ts +0 -19
- package/dist/types/frameworks/react/add-ons/form/assets/src/hooks/demo.form-context.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/form/assets/src/hooks/demo.form.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/mcp/assets/src/mcp-todos.d.ts +0 -7
- package/dist/types/frameworks/react/add-ons/mcp/assets/src/routes/demo/api.mcp-todos.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/mcp/assets/src/routes/mcp.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/mcp/assets/src/utils/mcp-handler.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/neon/assets/neon-vite-plugin.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/neon/assets/src/db.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/oRPC/assets/src/orpc/client.d.ts +0 -4
- package/dist/types/frameworks/react/add-ons/oRPC/assets/src/orpc/router/index.d.ts +0 -5
- package/dist/types/frameworks/react/add-ons/oRPC/assets/src/orpc/router/todos.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/oRPC/assets/src/orpc/schema.d.ts +0 -11
- package/dist/types/frameworks/react/add-ons/oRPC/assets/src/polyfill.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/oRPC/assets/src/routes/api.$.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/oRPC/assets/src/routes/api.rpc.$.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/shadcn/assets/src/lib/utils.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/start/assets/src/data/demo.punk-songs.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/start/assets/src/routes/demo/api.names.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/store/assets/src/lib/demo-store.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/storybook/assets/_dot_storybook/main.d.ts +0 -3
- package/dist/types/frameworks/react/add-ons/storybook/assets/_dot_storybook/preview.d.ts +0 -4
- package/dist/types/frameworks/react/add-ons/storybook/assets/src/components/storybook/button.stories.d.ts +0 -11
- package/dist/types/frameworks/react/add-ons/storybook/assets/src/components/storybook/input.stories.d.ts +0 -7
- package/dist/types/frameworks/react/add-ons/storybook/assets/src/components/storybook/radio-group.stories.d.ts +0 -7
- package/dist/types/frameworks/react/add-ons/storybook/assets/src/components/storybook/slider.stories.d.ts +0 -8
- package/dist/types/frameworks/react/add-ons/strapi/assets/src/lib/strapiClient.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/t3env/assets/src/env.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/tRPC/assets/src/integrations/trpc/init.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/tRPC/assets/src/integrations/trpc/react.d.ts +0 -1
- package/dist/types/frameworks/react/add-ons/tRPC/assets/src/integrations/trpc/router.d.ts +0 -2
- package/dist/types/frameworks/react/add-ons/table/assets/src/data/demo-table-data.d.ts +0 -11
- package/dist/types/frameworks/react/examples/events/assets/content-collections.d.ts +0 -2
- package/dist/types/frameworks/react/examples/events/assets/src/lib/conference-ai-hook.d.ts +0 -5
- package/dist/types/frameworks/react/examples/events/assets/src/lib/conference-tools.d.ts +0 -10
- package/dist/types/frameworks/react/examples/events/assets/src/lib/utils.d.ts +0 -2
- package/dist/types/frameworks/react/examples/events/assets/src/routes/api.remy-chat.d.ts +0 -1
- package/dist/types/frameworks/react/examples/resume/assets/content-collections.d.ts +0 -2
- package/dist/types/frameworks/react/examples/resume/assets/src/lib/resume-ai-hook.d.ts +0 -5
- package/dist/types/frameworks/react/examples/resume/assets/src/lib/resume-tools.d.ts +0 -8
- package/dist/types/frameworks/react/examples/resume/assets/src/lib/utils.d.ts +0 -2
- package/dist/types/frameworks/react/examples/resume/assets/src/routes/api.resume-chat.d.ts +0 -1
- package/dist/types/frameworks/solid/add-ons/better-auth/assets/src/lib/auth-client.d.ts +0 -1
- package/dist/types/frameworks/solid/add-ons/better-auth/assets/src/lib/auth.d.ts +0 -1
- package/dist/types/frameworks/solid/add-ons/better-auth/assets/src/routes/api/auth/$.d.ts +0 -1
- package/dist/types/frameworks/solid/add-ons/convex/assets/convex/schema.d.ts +0 -2
- package/dist/types/frameworks/solid/add-ons/convex/assets/convex/todos.d.ts +0 -4
- package/dist/types/frameworks/solid/add-ons/solid-ui/assets/src/lib/utils.d.ts +0 -2
- package/dist/types/frameworks/solid/add-ons/store/assets/src/lib/demo-store.d.ts +0 -2
- package/dist/types/frameworks/solid/add-ons/strapi/assets/src/lib/strapiClient.d.ts +0 -2
- package/dist/types/frameworks/solid/add-ons/t3env/assets/src/env.d.ts +0 -1
- package/dist/types/frameworks/solid/examples/tanchat/assets/ai-streaming-server/src/index.d.ts +0 -1
- package/dist/types/frameworks/solid/examples/tanchat/assets/src/lib/demo-store.d.ts +0 -2
- package/dist/types/frameworks/solid/examples/tanchat/assets/src/store/demo.hooks.d.ts +0 -23
- package/dist/types/frameworks/solid/examples/tanchat/assets/src/store/demo.store.d.ts +0 -40
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
import { chat } from '@tanstack/ai';
|
|
3
|
-
import { openaiText } from '@tanstack/ai-openai';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
// Schema for structured recipe output
|
|
6
|
-
const RecipeSchema = z.object({
|
|
7
|
-
name: z.string().describe('The name of the recipe'),
|
|
8
|
-
description: z.string().describe('A brief description of the dish'),
|
|
9
|
-
prepTime: z.string().describe('Preparation time (e.g., "15 minutes")'),
|
|
10
|
-
cookTime: z.string().describe('Cooking time (e.g., "30 minutes")'),
|
|
11
|
-
servings: z.number().describe('Number of servings'),
|
|
12
|
-
difficulty: z.enum(['easy', 'medium', 'hard']).describe('Difficulty level'),
|
|
13
|
-
ingredients: z
|
|
14
|
-
.array(z.object({
|
|
15
|
-
item: z.string().describe('Ingredient name'),
|
|
16
|
-
amount: z.string().describe('Amount needed (e.g., "2 cups")'),
|
|
17
|
-
notes: z.string().optional().describe('Optional preparation notes'),
|
|
18
|
-
}))
|
|
19
|
-
.describe('List of ingredients'),
|
|
20
|
-
instructions: z
|
|
21
|
-
.array(z.string())
|
|
22
|
-
.describe('Step-by-step cooking instructions'),
|
|
23
|
-
tips: z.array(z.string()).optional().describe('Optional cooking tips'),
|
|
24
|
-
nutritionPerServing: z
|
|
25
|
-
.object({
|
|
26
|
-
calories: z.number().optional(),
|
|
27
|
-
protein: z.string().optional(),
|
|
28
|
-
carbs: z.string().optional(),
|
|
29
|
-
fat: z.string().optional(),
|
|
30
|
-
})
|
|
31
|
-
.optional()
|
|
32
|
-
.describe('Nutritional information per serving'),
|
|
33
|
-
});
|
|
34
|
-
export const Route = createFileRoute('/demo/api/ai/structured')({
|
|
35
|
-
server: {
|
|
36
|
-
handlers: {
|
|
37
|
-
POST: async ({ request }) => {
|
|
38
|
-
const body = await request.json();
|
|
39
|
-
const { recipeName, mode = 'structured' } = body;
|
|
40
|
-
if (!recipeName || recipeName.trim().length === 0) {
|
|
41
|
-
return new Response(JSON.stringify({
|
|
42
|
-
error: 'Recipe name is required',
|
|
43
|
-
}), {
|
|
44
|
-
status: 400,
|
|
45
|
-
headers: { 'Content-Type': 'application/json' },
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
if (mode === 'structured') {
|
|
50
|
-
// Structured output mode - returns validated object
|
|
51
|
-
const result = await chat({
|
|
52
|
-
adapter: openaiText('gpt-4o'),
|
|
53
|
-
messages: [
|
|
54
|
-
{
|
|
55
|
-
role: 'user',
|
|
56
|
-
content: `Generate a complete recipe for: ${recipeName}. Include all ingredients with amounts, step-by-step instructions, prep/cook times, and difficulty level.`,
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
outputSchema: RecipeSchema,
|
|
60
|
-
});
|
|
61
|
-
return new Response(JSON.stringify({
|
|
62
|
-
mode: 'structured',
|
|
63
|
-
recipe: result,
|
|
64
|
-
provider: 'openai',
|
|
65
|
-
model: 'gpt-4o',
|
|
66
|
-
}), {
|
|
67
|
-
status: 200,
|
|
68
|
-
headers: { 'Content-Type': 'application/json' },
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
// One-shot markdown mode - returns text
|
|
73
|
-
const markdown = await chat({
|
|
74
|
-
adapter: openaiText('gpt-4o'),
|
|
75
|
-
stream: false,
|
|
76
|
-
messages: [
|
|
77
|
-
{
|
|
78
|
-
role: 'user',
|
|
79
|
-
content: `Generate a complete recipe for: ${recipeName}.
|
|
80
|
-
|
|
81
|
-
Format the recipe in beautiful markdown with:
|
|
82
|
-
- A title with the recipe name
|
|
83
|
-
- A brief description
|
|
84
|
-
- Prep time, cook time, and servings
|
|
85
|
-
- Ingredients list with amounts
|
|
86
|
-
- Numbered step-by-step instructions
|
|
87
|
-
- Optional tips section
|
|
88
|
-
- Nutritional info if applicable
|
|
89
|
-
|
|
90
|
-
Make it detailed and easy to follow.`,
|
|
91
|
-
},
|
|
92
|
-
],
|
|
93
|
-
});
|
|
94
|
-
return new Response(JSON.stringify({
|
|
95
|
-
mode: 'oneshot',
|
|
96
|
-
markdown,
|
|
97
|
-
provider: 'openai',
|
|
98
|
-
model: 'gpt-4o',
|
|
99
|
-
}), {
|
|
100
|
-
status: 200,
|
|
101
|
-
headers: { 'Content-Type': 'application/json' },
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
return new Response(JSON.stringify({
|
|
107
|
-
error: error.message || 'An error occurred',
|
|
108
|
-
}), {
|
|
109
|
-
status: 500,
|
|
110
|
-
headers: { 'Content-Type': 'application/json' },
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
});
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
import { generateTranscription } from '@tanstack/ai';
|
|
3
|
-
import { openaiTranscription } from '@tanstack/ai-openai';
|
|
4
|
-
export const Route = createFileRoute('/demo/api/ai/transcription')({
|
|
5
|
-
server: {
|
|
6
|
-
handlers: {
|
|
7
|
-
POST: async ({ request }) => {
|
|
8
|
-
const formData = await request.formData();
|
|
9
|
-
const audioFile = formData.get('audio');
|
|
10
|
-
const audioBase64 = formData.get('audioBase64');
|
|
11
|
-
const model = formData.get('model') || 'whisper-1';
|
|
12
|
-
const language = formData.get('language');
|
|
13
|
-
const responseFormat = formData.get('responseFormat');
|
|
14
|
-
if (!audioFile && !audioBase64) {
|
|
15
|
-
return new Response(JSON.stringify({
|
|
16
|
-
error: 'Audio file or base64 data is required',
|
|
17
|
-
}), {
|
|
18
|
-
status: 400,
|
|
19
|
-
headers: { 'Content-Type': 'application/json' },
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
if (!process.env.OPENAI_API_KEY) {
|
|
23
|
-
return new Response(JSON.stringify({
|
|
24
|
-
error: 'OPENAI_API_KEY is not configured',
|
|
25
|
-
}), {
|
|
26
|
-
status: 500,
|
|
27
|
-
headers: { 'Content-Type': 'application/json' },
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
try {
|
|
31
|
-
const adapter = openaiTranscription(model);
|
|
32
|
-
// Prepare audio data
|
|
33
|
-
let audioData;
|
|
34
|
-
if (audioFile) {
|
|
35
|
-
audioData = audioFile;
|
|
36
|
-
}
|
|
37
|
-
else if (audioBase64) {
|
|
38
|
-
audioData = audioBase64;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
throw new Error('No audio data provided');
|
|
42
|
-
}
|
|
43
|
-
const result = await generateTranscription({
|
|
44
|
-
adapter,
|
|
45
|
-
audio: audioData,
|
|
46
|
-
language: language || undefined,
|
|
47
|
-
responseFormat: responseFormat || 'verbose_json',
|
|
48
|
-
});
|
|
49
|
-
return new Response(JSON.stringify({
|
|
50
|
-
id: result.id,
|
|
51
|
-
model: result.model,
|
|
52
|
-
text: result.text,
|
|
53
|
-
language: result.language,
|
|
54
|
-
duration: result.duration,
|
|
55
|
-
segments: result.segments,
|
|
56
|
-
words: result.words,
|
|
57
|
-
}), {
|
|
58
|
-
status: 200,
|
|
59
|
-
headers: { 'Content-Type': 'application/json' },
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
return new Response(JSON.stringify({
|
|
64
|
-
error: error.message || 'An error occurred',
|
|
65
|
-
}), {
|
|
66
|
-
status: 500,
|
|
67
|
-
headers: { 'Content-Type': 'application/json' },
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
});
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
import { generateSpeech } from '@tanstack/ai';
|
|
3
|
-
import { openaiSpeech } from '@tanstack/ai-openai';
|
|
4
|
-
export const Route = createFileRoute('/demo/api/ai/tts')({
|
|
5
|
-
server: {
|
|
6
|
-
handlers: {
|
|
7
|
-
POST: async ({ request }) => {
|
|
8
|
-
const body = await request.json();
|
|
9
|
-
const { text, voice = 'alloy', model = 'tts-1', format = 'mp3', speed = 1.0, } = body;
|
|
10
|
-
if (!text || text.trim().length === 0) {
|
|
11
|
-
return new Response(JSON.stringify({
|
|
12
|
-
error: 'Text is required',
|
|
13
|
-
}), {
|
|
14
|
-
status: 400,
|
|
15
|
-
headers: { 'Content-Type': 'application/json' },
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
if (!process.env.OPENAI_API_KEY) {
|
|
19
|
-
return new Response(JSON.stringify({
|
|
20
|
-
error: 'OPENAI_API_KEY is not configured',
|
|
21
|
-
}), {
|
|
22
|
-
status: 500,
|
|
23
|
-
headers: { 'Content-Type': 'application/json' },
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
try {
|
|
27
|
-
const adapter = openaiSpeech(model);
|
|
28
|
-
const result = await generateSpeech({
|
|
29
|
-
adapter,
|
|
30
|
-
text,
|
|
31
|
-
voice,
|
|
32
|
-
format,
|
|
33
|
-
speed,
|
|
34
|
-
});
|
|
35
|
-
return new Response(JSON.stringify({
|
|
36
|
-
id: result.id,
|
|
37
|
-
model: result.model,
|
|
38
|
-
audio: result.audio,
|
|
39
|
-
format: result.format,
|
|
40
|
-
contentType: result.contentType,
|
|
41
|
-
duration: result.duration,
|
|
42
|
-
}), {
|
|
43
|
-
status: 200,
|
|
44
|
-
headers: { 'Content-Type': 'application/json' },
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
return new Response(JSON.stringify({
|
|
49
|
-
error: error.message || 'An error occurred',
|
|
50
|
-
}), {
|
|
51
|
-
status: 500,
|
|
52
|
-
headers: { 'Content-Type': 'application/json' },
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
});
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
import { auth } from '@/lib/auth';
|
|
3
|
-
export const Route = createFileRoute('/api/auth/$')({
|
|
4
|
-
server: {
|
|
5
|
-
handlers: {
|
|
6
|
-
GET: ({ request }) => auth.handler(request),
|
|
7
|
-
POST: ({ request }) => auth.handler(request),
|
|
8
|
-
},
|
|
9
|
-
},
|
|
10
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineSchema, defineTable } from 'convex/server';
|
|
2
|
-
import { v } from 'convex/values';
|
|
3
|
-
export default defineSchema({
|
|
4
|
-
products: defineTable({
|
|
5
|
-
title: v.string(),
|
|
6
|
-
imageId: v.string(),
|
|
7
|
-
price: v.number(),
|
|
8
|
-
}),
|
|
9
|
-
todos: defineTable({
|
|
10
|
-
text: v.string(),
|
|
11
|
-
completed: v.boolean(),
|
|
12
|
-
}),
|
|
13
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { mutation, query } from './_generated/server';
|
|
2
|
-
import { v } from 'convex/values';
|
|
3
|
-
export const list = query({
|
|
4
|
-
args: {},
|
|
5
|
-
handler: async (ctx) => {
|
|
6
|
-
return await ctx.db
|
|
7
|
-
.query('todos')
|
|
8
|
-
.withIndex('by_creation_time')
|
|
9
|
-
.order('desc')
|
|
10
|
-
.collect();
|
|
11
|
-
},
|
|
12
|
-
});
|
|
13
|
-
export const add = mutation({
|
|
14
|
-
args: { text: v.string() },
|
|
15
|
-
handler: async (ctx, args) => {
|
|
16
|
-
return await ctx.db.insert('todos', {
|
|
17
|
-
text: args.text,
|
|
18
|
-
completed: false,
|
|
19
|
-
});
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
export const toggle = mutation({
|
|
23
|
-
args: { id: v.id('todos') },
|
|
24
|
-
handler: async (ctx, args) => {
|
|
25
|
-
const todo = await ctx.db.get(args.id);
|
|
26
|
-
if (!todo) {
|
|
27
|
-
throw new Error('Todo not found');
|
|
28
|
-
}
|
|
29
|
-
return await ctx.db.patch(args.id, {
|
|
30
|
-
completed: !todo.completed,
|
|
31
|
-
});
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
export const remove = mutation({
|
|
35
|
-
args: { id: v.id('todos') },
|
|
36
|
-
handler: async (ctx, args) => {
|
|
37
|
-
return await ctx.db.delete(args.id);
|
|
38
|
-
},
|
|
39
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { createCollection, localOnlyCollectionOptions, } from "@tanstack/react-db";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
const MessageSchema = z.object({
|
|
4
|
-
id: z.number(),
|
|
5
|
-
text: z.string(),
|
|
6
|
-
user: z.string(),
|
|
7
|
-
});
|
|
8
|
-
export const messagesCollection = createCollection(localOnlyCollectionOptions({
|
|
9
|
-
getKey: (message) => message.id,
|
|
10
|
-
schema: MessageSchema,
|
|
11
|
-
}));
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef } from 'react';
|
|
2
|
-
import { useLiveQuery } from '@tanstack/react-db';
|
|
3
|
-
import { messagesCollection } from '@/db-collections';
|
|
4
|
-
function useStreamConnection(url, collection) {
|
|
5
|
-
const loadedRef = useRef(false);
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
const fetchData = async () => {
|
|
8
|
-
if (loadedRef.current)
|
|
9
|
-
return;
|
|
10
|
-
loadedRef.current = true;
|
|
11
|
-
const response = await fetch(url);
|
|
12
|
-
const reader = response.body?.getReader();
|
|
13
|
-
if (!reader) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
const decoder = new TextDecoder();
|
|
17
|
-
while (true) {
|
|
18
|
-
const { done, value } = await reader.read();
|
|
19
|
-
if (done)
|
|
20
|
-
break;
|
|
21
|
-
for (const chunk of decoder
|
|
22
|
-
.decode(value, { stream: true })
|
|
23
|
-
.split('\n')
|
|
24
|
-
.filter((chunk) => chunk.length > 0)) {
|
|
25
|
-
collection.insert(JSON.parse(chunk));
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
fetchData();
|
|
30
|
-
}, []);
|
|
31
|
-
}
|
|
32
|
-
export function useChat() {
|
|
33
|
-
useStreamConnection('/demo/db-chat-api', messagesCollection);
|
|
34
|
-
const sendMessage = (message, user) => {
|
|
35
|
-
fetch('/demo/db-chat-api', {
|
|
36
|
-
method: 'POST',
|
|
37
|
-
body: JSON.stringify({ text: message.trim(), user: user.trim() }),
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
return { sendMessage };
|
|
41
|
-
}
|
|
42
|
-
export function useMessages() {
|
|
43
|
-
const { data: messages } = useLiveQuery((q) => q.from({ message: messagesCollection }).select(({ message }) => ({
|
|
44
|
-
...message,
|
|
45
|
-
})));
|
|
46
|
-
return messages;
|
|
47
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
import { json } from '@tanstack/react-start';
|
|
3
|
-
import { createCollection, localOnlyCollectionOptions, } from '@tanstack/react-db';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
const IncomingMessageSchema = z.object({
|
|
6
|
-
user: z.string(),
|
|
7
|
-
text: z.string(),
|
|
8
|
-
});
|
|
9
|
-
const MessageSchema = IncomingMessageSchema.extend({
|
|
10
|
-
id: z.number(),
|
|
11
|
-
});
|
|
12
|
-
export const serverMessagesCollection = createCollection(localOnlyCollectionOptions({
|
|
13
|
-
getKey: (message) => message.id,
|
|
14
|
-
schema: MessageSchema,
|
|
15
|
-
}));
|
|
16
|
-
let id = 0;
|
|
17
|
-
serverMessagesCollection.insert({
|
|
18
|
-
id: id++,
|
|
19
|
-
user: 'Alice',
|
|
20
|
-
text: 'Hello, how are you?',
|
|
21
|
-
});
|
|
22
|
-
serverMessagesCollection.insert({
|
|
23
|
-
id: id++,
|
|
24
|
-
user: 'Bob',
|
|
25
|
-
text: "I'm fine, thank you!",
|
|
26
|
-
});
|
|
27
|
-
const sendMessage = (message) => {
|
|
28
|
-
serverMessagesCollection.insert({
|
|
29
|
-
id: id++,
|
|
30
|
-
user: message.user,
|
|
31
|
-
text: message.text,
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
export const Route = createFileRoute('/demo/db-chat-api')({
|
|
35
|
-
server: {
|
|
36
|
-
handlers: {
|
|
37
|
-
GET: () => {
|
|
38
|
-
const stream = new ReadableStream({
|
|
39
|
-
start(controller) {
|
|
40
|
-
for (const [_id, message] of serverMessagesCollection.state) {
|
|
41
|
-
controller.enqueue(JSON.stringify(message) + '\n');
|
|
42
|
-
}
|
|
43
|
-
serverMessagesCollection.subscribeChanges((changes) => {
|
|
44
|
-
for (const change of changes) {
|
|
45
|
-
if (change.type === 'insert') {
|
|
46
|
-
controller.enqueue(JSON.stringify(change.value) + '\n');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
return new Response(stream, {
|
|
53
|
-
headers: {
|
|
54
|
-
'Content-Type': 'application/x-ndjson',
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
},
|
|
58
|
-
POST: async ({ request }) => {
|
|
59
|
-
const message = IncomingMessageSchema.safeParse(await request.json());
|
|
60
|
-
if (!message.success) {
|
|
61
|
-
return new Response(message.error.message, { status: 400 });
|
|
62
|
-
}
|
|
63
|
-
sendMessage(message.data);
|
|
64
|
-
return json(message.data);
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { createFormHook } from '@tanstack/react-form';
|
|
2
|
-
import { Select, SubscribeButton, TextArea, TextField, } from '../components/demo.FormComponents';
|
|
3
|
-
import { fieldContext, formContext } from './demo.form-context';
|
|
4
|
-
export const { useAppForm } = createFormHook({
|
|
5
|
-
fieldComponents: {
|
|
6
|
-
TextField,
|
|
7
|
-
Select,
|
|
8
|
-
TextArea,
|
|
9
|
-
},
|
|
10
|
-
formComponents: {
|
|
11
|
-
SubscribeButton,
|
|
12
|
-
},
|
|
13
|
-
fieldContext,
|
|
14
|
-
formContext,
|
|
15
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
const todosPath = './mcp-todos.json';
|
|
3
|
-
// In-memory todos storage
|
|
4
|
-
const todos = fs.existsSync(todosPath)
|
|
5
|
-
? JSON.parse(fs.readFileSync(todosPath, 'utf8'))
|
|
6
|
-
: [
|
|
7
|
-
{
|
|
8
|
-
id: 1,
|
|
9
|
-
title: 'Buy groceries',
|
|
10
|
-
},
|
|
11
|
-
];
|
|
12
|
-
// Subscription callbacks per userID
|
|
13
|
-
let subscribers = [];
|
|
14
|
-
// Get the todos for a user
|
|
15
|
-
export function getTodos() {
|
|
16
|
-
return todos;
|
|
17
|
-
}
|
|
18
|
-
// Add an item to the todos
|
|
19
|
-
export function addTodo(title) {
|
|
20
|
-
todos.push({ id: todos.length + 1, title });
|
|
21
|
-
fs.writeFileSync(todosPath, JSON.stringify(todos, null, 2));
|
|
22
|
-
notifySubscribers();
|
|
23
|
-
}
|
|
24
|
-
// Subscribe to cart changes for a user
|
|
25
|
-
export function subscribeToTodos(callback) {
|
|
26
|
-
subscribers.push(callback);
|
|
27
|
-
callback(todos);
|
|
28
|
-
return () => {
|
|
29
|
-
subscribers = subscribers.filter((cb) => cb !== callback);
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
// Notify all subscribers of a user's cart
|
|
33
|
-
function notifySubscribers() {
|
|
34
|
-
for (const cb of subscribers) {
|
|
35
|
-
try {
|
|
36
|
-
cb(todos);
|
|
37
|
-
}
|
|
38
|
-
catch { }
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
import { addTodo, getTodos, subscribeToTodos } from '@/mcp-todos';
|
|
3
|
-
export const Route = createFileRoute('/api/mcp-todos')({
|
|
4
|
-
server: {
|
|
5
|
-
handlers: {
|
|
6
|
-
GET: () => {
|
|
7
|
-
const stream = new ReadableStream({
|
|
8
|
-
start(controller) {
|
|
9
|
-
function ping() {
|
|
10
|
-
try {
|
|
11
|
-
controller.enqueue(`event: ping\n\n`);
|
|
12
|
-
setTimeout(ping, 1000);
|
|
13
|
-
}
|
|
14
|
-
catch { }
|
|
15
|
-
}
|
|
16
|
-
ping();
|
|
17
|
-
const unsubscribe = subscribeToTodos((todos) => {
|
|
18
|
-
controller.enqueue(`data: ${JSON.stringify(todos)}\n\n`);
|
|
19
|
-
});
|
|
20
|
-
const todos = getTodos();
|
|
21
|
-
controller.enqueue(`data: ${JSON.stringify(todos)}\n\n`);
|
|
22
|
-
return () => unsubscribe();
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
return new Response(stream, {
|
|
26
|
-
headers: { 'Content-Type': 'text/event-stream' },
|
|
27
|
-
});
|
|
28
|
-
},
|
|
29
|
-
POST: async ({ request }) => {
|
|
30
|
-
const { title } = await request.json();
|
|
31
|
-
addTodo(title);
|
|
32
|
-
return Response.json(getTodos());
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
|
|
2
|
-
export async function handleMcpRequest(request, server) {
|
|
3
|
-
try {
|
|
4
|
-
const jsonRpcRequest = (await request.json());
|
|
5
|
-
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
6
|
-
let responseData = null;
|
|
7
|
-
clientTransport.onmessage = (message) => {
|
|
8
|
-
responseData = message;
|
|
9
|
-
};
|
|
10
|
-
await server.connect(serverTransport);
|
|
11
|
-
await clientTransport.start();
|
|
12
|
-
await serverTransport.start();
|
|
13
|
-
await clientTransport.send(jsonRpcRequest);
|
|
14
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
15
|
-
await clientTransport.close();
|
|
16
|
-
await serverTransport.close();
|
|
17
|
-
return Response.json(responseData, {
|
|
18
|
-
headers: {
|
|
19
|
-
'Content-Type': 'application/json',
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
console.error('MCP handler error:', error);
|
|
25
|
-
// Return a JSON-RPC error response
|
|
26
|
-
return Response.json({
|
|
27
|
-
jsonrpc: '2.0',
|
|
28
|
-
error: {
|
|
29
|
-
code: -32603,
|
|
30
|
-
message: 'Internal server error',
|
|
31
|
-
data: error instanceof Error ? error.message : String(error),
|
|
32
|
-
},
|
|
33
|
-
id: null,
|
|
34
|
-
}, {
|
|
35
|
-
status: 500,
|
|
36
|
-
headers: {
|
|
37
|
-
'Content-Type': 'application/json',
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { neon } from '@neondatabase/serverless';
|
|
2
|
-
let client;
|
|
3
|
-
export async function getClient() {
|
|
4
|
-
if (!process.env.VITE_DATABASE_URL) {
|
|
5
|
-
return undefined;
|
|
6
|
-
}
|
|
7
|
-
if (!client) {
|
|
8
|
-
client = await neon(process.env.VITE_DATABASE_URL);
|
|
9
|
-
}
|
|
10
|
-
return client;
|
|
11
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { createRouterClient } from '@orpc/server';
|
|
2
|
-
import { createORPCClient } from '@orpc/client';
|
|
3
|
-
import { RPCLink } from '@orpc/client/fetch';
|
|
4
|
-
import { createTanstackQueryUtils } from '@orpc/tanstack-query';
|
|
5
|
-
import { getRequestHeaders } from '@tanstack/react-start/server';
|
|
6
|
-
import { createIsomorphicFn } from '@tanstack/react-start';
|
|
7
|
-
import router from '@/orpc/router';
|
|
8
|
-
const getORPCClient = createIsomorphicFn()
|
|
9
|
-
.server(() => createRouterClient(router, {
|
|
10
|
-
context: () => ({
|
|
11
|
-
headers: getRequestHeaders(),
|
|
12
|
-
}),
|
|
13
|
-
}))
|
|
14
|
-
.client(() => {
|
|
15
|
-
const link = new RPCLink({
|
|
16
|
-
url: `${window.location.origin}/api/rpc`,
|
|
17
|
-
});
|
|
18
|
-
return createORPCClient(link);
|
|
19
|
-
});
|
|
20
|
-
export const client = getORPCClient();
|
|
21
|
-
export const orpc = createTanstackQueryUtils(client);
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { os } from '@orpc/server';
|
|
2
|
-
import * as z from 'zod';
|
|
3
|
-
const todos = [
|
|
4
|
-
{ id: 1, name: 'Get groceries' },
|
|
5
|
-
{ id: 2, name: 'Buy a new phone' },
|
|
6
|
-
{ id: 3, name: 'Finish the project' },
|
|
7
|
-
];
|
|
8
|
-
export const listTodos = os.input(z.object({})).handler(() => {
|
|
9
|
-
return todos;
|
|
10
|
-
});
|
|
11
|
-
export const addTodo = os
|
|
12
|
-
.input(z.object({ name: z.string() }))
|
|
13
|
-
.handler(({ input }) => {
|
|
14
|
-
const newTodo = { id: todos.length + 1, name: input.name };
|
|
15
|
-
todos.push(newTodo);
|
|
16
|
-
return newTodo;
|
|
17
|
-
});
|