- A TypeScript toolkit for building dynamic ai-generated UI with structured, streaming,
- immediately safe-to-parse JSON from OpenAI or AnyScale.
+ A TypeScript toolkit for building dynamic LLM generated UI with structured, streaming,
+ immediately safe-to-parse JSON.
-
+
-
-
-
diff --git a/apps/www/src/app/providers.tsx b/apps/www/src/app/providers.tsx
index cf75da6..8be3b21 100644
--- a/apps/www/src/app/providers.tsx
+++ b/apps/www/src/app/providers.tsx
@@ -1,6 +1,7 @@
"use client"
import { createContext, Dispatch, ReactNode, SetStateAction, useState } from "react"
+import { RootProvider } from "fumadocs-ui/provider"
import { ThemeProvider, useTheme } from "next-themes"
import { Toaster } from "sonner"
@@ -30,7 +31,7 @@ export default function Providers({ children }: { children: ReactNode }) {
}}
>
-
{children}
+ {children}
)
diff --git a/apps/www/src/components/doc-nav.tsx b/apps/www/src/components/doc-nav.tsx
deleted file mode 100644
index 9ed5e26..0000000
--- a/apps/www/src/components/doc-nav.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import Link from "next/link"
-import { ScrollArea } from "@repo/ui/components/ui/scroll-area"
-import { ArrowRight } from "lucide-react"
-
-import { docs, DocType } from "@/config/docs"
-
-export function DocNav({ packageConfig }: { packageConfig: DocType }) {
- return (
- <>
-
-
;
+}
+```
+
diff --git a/apps/www/src/content/docs/stream-hooks/index.mdx b/apps/www/src/content/docs/stream-hooks/index.mdx
new file mode 100644
index 0000000..99b4f71
--- /dev/null
+++ b/apps/www/src/content/docs/stream-hooks/index.mdx
@@ -0,0 +1,71 @@
+---
+
+title: Stream Hooks
+description: React hooks for processing streaming JSON data from LLMs with progressive validation
+---
+
+
+Hooks for consuming streams in react - specifically json streams coming from LLMS - given a Zod Schema that represents the final output, you can start the stream and start to read the structured result immediately.
+
+
+`stream-hooks` provides React hooks for consuming streams - specifically JSON streams coming from LLMs. Given a Zod Schema that represents the final output, you can start processing structured results immediately as they stream in.
+
+
+## Key Features
+
+- π React hooks for streaming LLM responses
+- π― Progressive validation and partial results
+- π Built-in TypeScript support
+- β‘ Seamless integration with zod-stream
+- π³ Path completion tracking
+- π Error handling and loading states
+
+## Integration with zod-stream
+
+`stream-hooks` was designed to work with `zod-stream` response modes:
+
+```typescript
+import { withResponseModel } from "zod-stream";
+
+// API Route
+export async function POST(req: Request) {
+ const params = withResponseModel({
+ response_model: {
+ schema,
+ name: "Analysis"
+ },
+ mode: "TOOLS",
+ params: {
+ messages: [{ role: "user", content: "..." }],
+ model: "gpt-4"
+ }
+ });
+
+ const completion = await openai.chat.completions.create({
+ ...params,
+ stream: true
+ });
+
+ return new Response(completion.body);
+}
+```
+
+## TypeScript Support
+
+The hook provides full type inference:
+
+```typescript
+const schema = z.object({
+ result: z.string(),
+ confidence: z.number()
+});
+
+// data is fully typed based on schema
+const { data } = useJsonStream({
+ schema,
+ onReceive: (data) => {
+ // TypeScript knows the shape of data
+ console.log(data.result, data.confidence);
+ }
+});
+```
diff --git a/apps/www/src/content/docs/zod-stream/examples.mdx b/apps/www/src/content/docs/zod-stream/examples.mdx
new file mode 100644
index 0000000..17182ee
--- /dev/null
+++ b/apps/www/src/content/docs/zod-stream/examples.mdx
@@ -0,0 +1,296 @@
+---
+title: Examples
+---
+I'll break down each example into smaller, annotated snippets that are easier to understand and copy. I'll start with the first example:
+
+### 1. Progressive Data Analysis
+
+First, let's define the schema:
+
+```typescript
+// Define the structure of our market analysis data
+const analysisSchema = z.object({
+ marketData: z.object({
+ trends: z.array(z.object({
+ metric: z.string(),
+ value: z.number()
+ })),
+ summary: z.string()
+ }),
+ competitors: z.array(z.object({
+ name: z.string(),
+ strengths: z.array(z.string()),
+ weaknesses: z.array(z.string())
+ })),
+ recommendations: z.object({
+ immediate: z.array(z.string()),
+ longTerm: z.array(z.string()),
+ budget: z.number()
+ })
+});
+```
+
+Then, handle the streaming data processing:
+
+```typescript
+for await (const chunk of stream) {
+ // 1. Visualize market trends as soon as they're available
+ if (isPathComplete(['marketData', 'trends'], chunk)) {
+ initializeCharts(chunk.marketData.trends);
+ }
+
+ // 2. Process competitor data as each competitor entry completes
+ chunk._meta._completedPaths.forEach(path => {
+ if (path[0] === 'competitors' && path.length === 2) {
+ const competitor = chunk.competitors[path[1] as number];
+ fetchCompetitorData(competitor.name);
+ }
+ });
+
+ // 3. Handle budget planning when both requirements are met
+ if (isPathComplete(['recommendations', 'immediate'], chunk) &&
+ isPathComplete(['recommendations', 'budget'], chunk)) {
+ planBudgetAllocation({
+ actions: chunk.recommendations.immediate,
+ budget: chunk.recommendations.budget
+ });
+ }
+}
+```
+
+### 2. Document Processing Pipeline
+
+The schema:
+
+```typescript
+const documentSchema = z.object({
+ metadata: z.object({
+ title: z.string(),
+ author: z.string(),
+ topics: z.array(z.string())
+ }),
+ sections: z.array(z.object({
+ heading: z.string(),
+ content: z.string(),
+ annotations: z.array(z.object({
+ type: z.string(),
+ text: z.string(),
+ confidence: z.number()
+ }))
+ })),
+ summary: z.object({
+ abstract: z.string(),
+ keyPoints: z.array(z.string()),
+ readingTime: z.number()
+ })
+});
+```
+
+The processing logic:
+
+```typescript
+for await (const chunk of stream) {
+ // 1. Start document indexing when metadata arrives
+ if (isPathComplete(['metadata'], chunk)) {
+ indexDocument({
+ title: chunk.metadata.title,
+ topics: chunk.metadata.topics
+ });
+ }
+
+ // 2. Process section annotations as they complete
+ chunk._meta._completedPaths.forEach(path => {
+ if (path[0] === 'sections' && isPathComplete([...path, 'annotations'], chunk)) {
+ const sectionIndex = path[1] as number;
+ const section = chunk.sections[sectionIndex];
+ processAnnotations({
+ heading: section.heading,
+ annotations: section.annotations
+ });
+ }
+ });
+
+ // 3. Generate preview when required fields are available
+ if (isPathComplete(['summary', 'abstract'], chunk) &&
+ isPathComplete(['summary', 'readingTime'], chunk)) {
+ generatePreview({
+ abstract: chunk.summary.abstract,
+ readingTime: chunk.summary.readingTime
+ });
+ }
+}
+```
+
+### 3. E-commerce Product Enrichment
+
+The schema:
+
+```typescript
+const productSchema = z.object({
+ basic: z.object({
+ id: z.string(),
+ name: z.string(),
+ category: z.string()
+ }),
+ pricing: z.object({
+ base: z.number(),
+ discounts: z.array(z.object({
+ type: z.string(),
+ amount: z.number()
+ })),
+ final: z.number()
+ }),
+ inventory: z.object({
+ status: z.string(),
+ locations: z.array(z.object({
+ id: z.string(),
+ quantity: z.number()
+ }))
+ }),
+ enrichment: z.object({
+ seoDescription: z.string(),
+ searchKeywords: z.array(z.string()),
+ relatedProducts: z.array(z.string())
+ })
+});
+```
+
+The processing logic:
+
+```typescript
+for await (const chunk of stream) {
+ // 1. Initialize product display with basic info
+ if (isPathComplete(['basic'], chunk)) {
+ initializeProductCard(chunk.basic);
+ }
+
+ // 2. Handle pricing and inventory updates
+ if (isPathComplete(['pricing', 'final'], chunk)) {
+ updatePriceDisplay(chunk.pricing.final);
+
+ if (isPathComplete(['inventory', 'status'], chunk)) {
+ updateBuyButton({
+ price: chunk.pricing.final,
+ status: chunk.inventory.status
+ });
+ }
+ }
+
+ // 3. Handle SEO optimization
+ if (isPathComplete(['enrichment', 'seoDescription'], chunk) &&
+ isPathComplete(['enrichment', 'searchKeywords'], chunk)) {
+ optimizeProductSEO({
+ description: chunk.enrichment.seoDescription,
+ keywords: chunk.enrichment.searchKeywords
+ });
+ }
+
+ // 4. Handle related products
+ if (isPathComplete(['enrichment', 'relatedProducts'], chunk)) {
+ prefetchRelatedProducts(chunk.enrichment.relatedProducts);
+ }
+}
+```
+
+### Next.js API Route Example
+
+The schema:
+
+```typescript
+// schemas/analysis.ts
+const schema = z.object({
+ summary: z.string(),
+ topics: z.array(z.string()),
+ sentiment: z.object({
+ score: z.number(),
+ label: z.string()
+ })
+});
+```
+
+The API route:
+
+```typescript
+// pages/api/extract.ts
+import { withResponseModel, OAIStream } from "zod-stream";
+import { z } from "zod";
+import { analysisSchema } from "@/schemas/analysis";
+
+// 2. Create the API handler
+export default async function handler(req, res) {
+ const { content } = await req.json();
+
+ // 3. Configure the response model
+ const params = withResponseModel({
+ response_model: {
+ schema,
+ name: "ContentAnalysis"
+ },
+ mode: "TOOLS",
+ params: {
+ messages: [{
+ role: "user",
+ content: `Analyze: ${content}`
+ }],
+ model: "gpt-4"
+ }
+ });
+
+ // 4. Create and return the stream
+ const stream = await oai.chat.completions.create({
+ ...params,
+ stream: true
+ });
+
+ return new Response(OAIStream({ res: stream }));
+}
+```
+
+### React Component Example
+
+```typescript
+import { useJsonStream } from "stream-hooks";
+import { analysisSchema } from "@/schemas/analysis";
+import { z } from "zod";
+
+
+function AnalysisComponent() {
+ const [data, setData] = useState>();
+
+
+ const {
+ loading,
+ error,
+ startStream
+ } = useJsonStream({
+ schema,
+ onReceive: (data) => {
+ setData(data)
+ }
+ });
+
+
+ return (
+
+
+
+ {loading && }
+ {error && }
+
+ 0}
+ />
+
+ );
+}
+```
\ No newline at end of file
diff --git a/apps/www/src/content/docs/zod-stream/getting-started.mdx b/apps/www/src/content/docs/zod-stream/getting-started.mdx
new file mode 100644
index 0000000..d01aa66
--- /dev/null
+++ b/apps/www/src/content/docs/zod-stream/getting-started.mdx
@@ -0,0 +1,452 @@
+---
+title: Getting Started
+---
+
+import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
+
+## Installation
+
+
+
+ ```bash
+ bun add zod-stream zod openai
+ ```
+
+
+ ```bash
+ npm install zod-stream zod openai
+ ```
+
+
+ ```bash
+ pnpm add zod-stream zod openai
+ ```
+
+
+
+
+
+## Core Concepts
+
+The `ZodStream` client provides real-time validation and metadata for streaming LLM responses:
+
+```typescript
+import ZodStream from "zod-stream";
+import { z } from "zod";
+
+const client = new ZodStream({
+ debug: true // Enable debug logging
+});
+
+// Define your extraction schema
+const schema = z.object({
+ content: z.string(),
+ metadata: z.object({
+ confidence: z.number(),
+ category: z.string()
+ })
+});
+
+// Create streaming extraction
+const stream = await client.create({
+ completionPromise: async () => {
+ const response = await fetch("/api/extract", {
+ method: "POST",
+ body: JSON.stringify({ prompt: "..." })
+ });
+ return response.body;
+ },
+ response_model: {
+ schema,
+ name: "ContentExtraction"
+ }
+});
+
+// Process with validation metadata
+for await (const chunk of stream) {
+ console.log({
+ data: chunk, // Partial extraction result
+ isValid: chunk._meta._isValid, // Current validation state
+ activePath: chunk._meta._activePath, // Currently processing path
+ completedPaths: chunk._meta._completedPaths // Completed paths
+ });
+}
+```
+
+## Progressive Processing
+
+`zod-stream` enables processing dependent data as soon as relevant paths complete, without waiting for the full response:
+
+```typescript
+// Define schema for a complex analysis
+const schema = z.object({
+ user: z.object({
+ id: z.string(),
+ preferences: z.object({
+ theme: z.string(),
+ language: z.string()
+ })
+ }),
+ content: z.object({
+ title: z.string(),
+ body: z.string(),
+ metadata: z.object({
+ keywords: z.array(z.string()),
+ category: z.string()
+ })
+ }),
+ recommendations: z.array(z.object({
+ id: z.string(),
+ score: z.number(),
+ reason: z.string()
+ }))
+});
+
+// Process data as it becomes available
+for await (const chunk of stream) {
+ // Start personalizing UI as soon as user preferences are ready
+ if (isPathComplete(['user', 'preferences'], chunk)) {
+ applyUserTheme(chunk.user.preferences.theme);
+ setLanguage(chunk.user.preferences.language);
+ }
+
+ // Begin content indexing once we have title and keywords
+ if (isPathComplete(['content', 'metadata', 'keywords'], chunk) &&
+ isPathComplete(['content', 'title'], chunk)) {
+ indexContent({
+ title: chunk.content.title,
+ keywords: chunk.content.metadata.keywords
+ });
+ }
+
+ // Start fetching recommended content in parallel
+ chunk._meta._completedPaths.forEach(path => {
+ if (path[0] === 'recommendations' && path.length === 2) {
+ const index = path[1] as number;
+ const recommendation = chunk.recommendations[index];
+
+ if (recommendation?.id) {
+ prefetchContent(recommendation.id);
+ }
+ }
+ });
+}
+```
+
+This approach enables:
+
+- Early UI updates based on user preferences
+- Parallel processing of independent data
+- Optimistic loading of related content
+- Better perceived performance
+- Resource optimization
+
+## Stream Metadata
+
+Every streamed chunk includes metadata about validation state:
+
+```typescript
+type CompletionMeta = {
+ _isValid: boolean; // Schema validation status
+ _activePath: (string | number)[]; // Current parsing path
+ _completedPaths: (string | number)[][]; // All completed paths
+}
+
+// Example chunk
+{
+ content: "partial content...",
+ metadata: {
+ confidence: 0.95
+ },
+ _meta: {
+ _isValid: false, // Not valid yet
+ _activePath: ["metadata", "category"],
+ _completedPaths: [
+ ["content"],
+ ["metadata", "confidence"]
+ ]
+ }
+}
+```
+
+## Schema Stubs
+
+Get typed stub objects for initialization:
+
+```typescript
+const schema = z.object({
+ users: z.array(z.object({
+ name: z.string(),
+ age: z.number()
+ }))
+});
+
+const client = new ZodStream();
+const stub = client.getSchemaStub({
+ schema,
+ defaultData: {
+ users: [{ name: "loading...", age: 0 }]
+ }
+});
+```
+
+## Debug Logging
+
+Enable detailed logging for debugging:
+
+```typescript
+const client = new ZodStream({ debug: true });
+
+// Logs will include:
+// - Stream initialization
+// - Validation results
+// - Path completion
+// - Errors with full context
+```
+
+### Using Response Models
+
+The `withResponseModel` helper configures OpenAI parameters based on your schema and chosen mode:
+
+```typescript
+import { withResponseModel } from "zod-stream";
+import { z } from "zod";
+
+const schema = z.object({
+ sentiment: z.string(),
+ keywords: z.array(z.string()),
+ confidence: z.number()
+});
+
+// Configure for OpenAI tools mode
+const params = withResponseModel({
+ response_model: {
+ schema,
+ name: "Analysis",
+ description: "Extract sentiment and keywords"
+ },
+ mode: "TOOLS",
+ params: {
+ messages: [{ role: "user", content: "Analyze this text..." }],
+ model: "gpt-4"
+ }
+});
+
+const completion = await oai.chat.completions.create({
+ ...params,
+ stream: true
+});
+```
+
+## Response Modes
+
+`zod-stream` supports multiple modes for structured LLM responses:
+
+```typescript
+import { MODE } from "zod-stream";
+
+const modes = {
+ FUNCTIONS: "FUNCTIONS", // OpenAI function calling
+ TOOLS: "TOOLS", // OpenAI tools API
+ JSON: "JSON", // Direct JSON response
+ MD_JSON: "MD_JSON", // JSON in markdown blocks
+ JSON_SCHEMA: "JSON_SCHEMA" // JSON with schema validation
+} as const;
+```
+
+
+### Mode-Specific Behaviors
+
+#### TOOLS Mode
+
+```typescript
+// Results in OpenAI tool configuration
+{
+ tool_choice: {
+ type: "function",
+ function: { name: "Analysis" }
+ },
+ tools: [{
+ type: "function",
+ function: {
+ name: "Analysis",
+ description: "Extract sentiment and keywords",
+ parameters: {/* Generated from schema */}
+ }
+ }],
+ // ... other existing params are preserved
+}
+```
+
+#### FUNCTIONS Mode (Legacy)
+
+```typescript
+// Results in OpenAI function configuration
+{
+ function_call: { name: "Analysis" },
+ functions: [{
+ name: "Analysis",
+ description: "Extract sentiment and keywords",
+ parameters: {/* Generated from schema */}
+ }],
+ // ... other existing params are preserved
+}
+```
+
+#### JSON Mode
+
+```typescript
+// Results in direct JSON response configuration
+{
+ response_format: { type: "json_object" },
+ messages: [
+ {
+ role: "system",
+ content: `
+ Given a user prompt, you will return fully valid JSON based on the following description and schema.
+ You will return no other prose. You will take into account any descriptions or required parameters within the schema
+ and return a valid and fully escaped JSON object that matches the schema and those instructions.
+
+ description: ${definition.description}
+ json schema: ${JSON.stringify(definition)}
+ `
+ },
+ // ... user messages are preserved
+ ]
+}
+```
+
+#### JSON_SCHEMA Mode
+
+```typescript
+// Results in JSON schema-based configuration
+{
+ response_format: {
+ type: "json_object",
+ schema: {/* Schema without name and description */}
+ },
+ messages: [
+ {
+ role: "system",
+ content: `
+ Given a user prompt, you will return fully valid JSON based on the following description.
+ You will return no other prose. You will take into account any descriptions or required parameters within the schema
+ and return a valid and fully escaped JSON object that matches the schema and those instructions.
+
+ description: ${definition.description}
+ `
+ },
+ // ... user messages are preserved
+ ]
+}
+```
+
+#### MESSAGE_BASED Mode
+
+```typescript
+// Similar to JSON mode but without response_format
+{
+ messages: [
+ {
+ role: "system",
+ content: `
+ Given a user prompt, you will return fully valid JSON based on the following description and schema.
+ You will return no other prose. You will take into account any descriptions or required parameters within the schema
+ and return a valid and fully escaped JSON object that matches the schema and those instructions.
+
+ description: ${definition.description}
+ json schema: ${JSON.stringify(definition)}
+ `
+ },
+ // ... user messages are preserved
+ ]
+}
+```
+
+### Response Parsing
+
+Built-in parsers handle different response formats:
+
+```typescript
+import {
+ OAIResponseParser,
+ OAIResponseToolArgsParser,
+ OAIResponseFnArgsParser,
+ OAIResponseJSONParser
+} from "zod-stream";
+
+// Automatic format detection
+const result = OAIResponseParser(response);
+
+// Format-specific parsing
+const toolArgs = OAIResponseToolArgsParser(response);
+const fnArgs = OAIResponseFnArgsParser(response);
+const jsonContent = OAIResponseJSONParser(response);
+```
+
+### Streaming Utilities
+
+Handle streaming responses with built-in utilities:
+
+```typescript
+import { OAIStream, readableStreamToAsyncGenerator } from "zod-stream";
+
+// Create streaming response
+app.post("/api/stream", async (req, res) => {
+ const completion = await oai.chat.completions.create({
+ ...params,
+ stream: true
+ });
+
+ return new Response(
+ OAIStream({ res: completion })
+ );
+});
+
+// Convert stream to async generator
+const generator = readableStreamToAsyncGenerator(stream);
+for await (const chunk of generator) {
+ console.log(chunk);
+}
+```
+
+### Path Tracking Utilities
+
+Monitor completion status of specific paths:
+
+```typescript
+import { isPathComplete } from "zod-stream";
+
+const activePath = ["analysis", "sentiment"];
+const isComplete = isPathComplete(activePath, {
+ _meta: {
+ _completedPaths: [["analysis", "sentiment"]],
+ _activePath: ["analysis", "keywords"],
+ _isValid: false
+ }
+});
+```
+
+## Error Handling
+
+`zod-stream` provides error handling at multiple levels:
+
+```typescript
+const stream = await client.create({
+ completionPromise: async () => response.body,
+ response_model: { schema }
+});
+
+let finalResult
+
+// Path tracking for progressive updates
+for await (const chunk of stream) {
+ finalResult = chunk
+ // Check which paths are complete
+ console.log("Completed paths:", chunk._meta._completedPaths);
+ console.log("Current path:", chunk._meta._activePath);
+}
+
+// Final validation happens after stream completes
+const isValid = finalResult._meta._isValid
+```
diff --git a/apps/www/src/content/docs/zod-stream/index.mdx b/apps/www/src/content/docs/zod-stream/index.mdx
new file mode 100644
index 0000000..088d5aa
--- /dev/null
+++ b/apps/www/src/content/docs/zod-stream/index.mdx
@@ -0,0 +1,66 @@
+---
+title: Zod Stream
+description: Type-safe structured extraction from LLM streams with progressive validation
+---
+
+
+`zod-stream` adds structured output validation and streaming capabilities to LLM responses. Built on top of [`schema-stream`](/docs/schema-stream), it enables type-safe extraction with progressive validation.
+
+
+
+## Key Features
+
+- π Stream structured LLM outputs with validation
+- π― Multiple response modes (TOOLS, FUNCTIONS, JSON, etc.)
+- π OpenAI client integration
+- π³ Progressive validation with partial results
+- β‘ Built on schema-stream
+- π Full TypeScript support
+
+## Why zod-stream?
+
+`zod-stream` solves key challenges in handling streaming LLM responses:
+
+- **Dependency Management**: Process data as soon as dependencies are met, rather than waiting for complete responses
+
+ ```typescript
+ if (isPathComplete(['user', 'preferences'], chunk)) {
+ // Start personalizing immediately, don't wait for content
+ initializeUserExperience(chunk.user.preferences);
+ }
+ ```
+
+- **Type-Safe LLM Integration**: Full TypeScript support for structured outputs from OpenAI and other providers
+
+ ```typescript
+ const params = withResponseModel({
+ response_model: { schema, name: "Extract" },
+ mode: "TOOLS" // or "FUNCTIONS", "JSON", etc.
+ });
+ ```
+
+- **Progressive Processing**: Built on `schema-stream` for immediate access to partial results
+
+ ```typescript
+ for await (const chunk of stream) {
+ // Safely access partial data with full type inference
+ chunk._meta._completedPaths.forEach(path => {
+ processDependency(path, chunk);
+ });
+ }
+ ```
+
+- **Provider Flexibility**: Consistent interface across different LLM response formats
+
+ ```typescript
+ // Works with various response modes
+ const stream = OAIStream({ res: completion }); // OpenAI tools/functions
+ const stream = JSONStream({ res: completion }); // Direct JSON
+ ```
+
+Think of it as a type-safe pipeline for handling streaming LLM data where you need to:
+
+- Start processing before the full response arrives
+- Ensure type safety throughout the stream
+- Handle complex data dependencies
+- Work with multiple LLM response formats
diff --git a/apps/www/src/docs/concepts.mdx b/apps/www/src/docs/concepts.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/apps/www/src/docs/evalz.mdx b/apps/www/src/docs/evalz.mdx
deleted file mode 100644
index aff6372..0000000
--- a/apps/www/src/docs/evalz.mdx
+++ /dev/null
@@ -1,13 +0,0 @@
-# evalz
-
-## Introduction
-
-### Overview
-**evalz** is a TypeScript package designed to facilitate model-graded evaluations with a focus on structured output. Leveraging Zod schemas, **evalz** streamline s the evaluation of AI-generated responses. It provides a set of tools to assess the quality of responses based on custom criteria such as relevance, fluency, and completeness. The package leverages OpenAI's GPT models to perform evaluations, offering both simple and weighted evaluation mechanisms.
-
-### Key Features
-- **Structured Evaluation Models**: Define your evaluation logic using Zod schemas to ensure data integrity throughout your application.
-- **Flexible Evaluation Strategies**: Supports various evaluation strategies, including score-based and binary evaluations, with customizable evaluators.
-- **Easy Integration**: Designed to integrate seamlessly with existing TypeScript projects, enhancing AI and data processing workflows with minimal setup.
-- **Custom Evaluations**: Define evaluation criteria tailored to your specific requirements.
-- **Weighted Evaluations**: Combine multiple evaluations with custom weights to calculate a composite score.
diff --git a/apps/www/src/docs/overview-concepts-structured-responses.mdx b/apps/www/src/docs/overview-concepts-structured-responses.mdx
deleted file mode 100644
index ca910f6..0000000
--- a/apps/www/src/docs/overview-concepts-structured-responses.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
-# Concepts: Structured Responses and Partial Streaming
-
-## Structured Responses in Island AI
-
-### What Are Structured Responses?
-- **Definition**: In Island AI, structured responses are JSON-formatted data outputs structured according to Zod schemas. These schemas define the expected format of the AI's output, making the data predictable and easy to integrate into various parts of the UI.
-
-- **Application**: Structured responses enable a range of functionalities, from responding to user queries to defining side effects for application execution. They allow for versatile use of the data, such as splitting the response to feed into different UI components.
-
-### Island AI's Approach
-- **Abstraction of Complexity**: Island AI abstracts the complexity of tools like OpenAI's functions and JSON mode. You focus on defining the Zod schema for the desired response model, which Island AI uses to handle the output from AI systems efficiently and safely.
diff --git a/apps/www/src/docs/overview-instructor.mdx b/apps/www/src/docs/overview-instructor.mdx
deleted file mode 100644
index 5afe225..0000000
--- a/apps/www/src/docs/overview-instructor.mdx
+++ /dev/null
@@ -1,39 +0,0 @@
-# Understanding Instructor
-
-
-## What is Island AI?
-Island AI is a suite of TypeScript packages focused on building dynamic, responsive UIs for AI applications. It's tailored to handle streaming JSON data efficiently, making it ideal for web applications that require real-time updates and interactions. The core of Island AI lies in:
-
- - Streamlined data handling, particularly for streaming JSON
- - Facilitating dynamic user interfaces in browser environments
- - Providing tools like zod-stream and React hooks to manage and display data updates in real time
-
-## What is Instructor?
-Instructor, on the other hand, is a TypeScript library primarily designed for structured data extraction and validation in server environments. It stands out in scenarios that require robust validation, retries, and complex data manipulation, often backed by AI models like those from OpenAI. Key aspects of Instructor include:
-
-- Focused on server-side structured data extraction and validation
-- Utilizes schema-stream for handling JSON streams, similar to zod-stream
-- Offers a comprehensive approach to managing the entire streaming and validation process
-- Ideal for tasks that require intricate data parsing and manipulation, backed by a variety of - functionalities outlined in the Instructor cookbook
-
-
-## How Do They Complement Each Other?
-While Island AI and Instructor serve different purposes, they complement each other in the broader landscape of AI-driven application development:
-
-- Island AI excels in client-side dynamics, making it a go-to choice for developers looking to build interactive and responsive UIs that react in real time to streaming data.
-- Instructor is more suited for server-side operations where structured data extraction and validation are critical, especially when dealing with complex AI-driven responses.
-
-## Use Cases and Integration
-
-In scenarios where you need to process and display streaming data in real-time on the client side, Island AI's tools would be the preferred choice.
-
-For server-side applications that require intricate data handling, validation, and extraction, particularly when working with AI models like GPT-3, Instructor provides a robust solution.
-Developers can leverage both sets of tools in a single application, using Instructor for server-side data processing and Island AI for real-time client-side interactions.
-
-## Future Developments
-Plans to integrate aspects of Island AI into Instructor will further streamline the development process, offering a more cohesive toolkit for handling AI-driven data across both client and server environments.
-
-## Conclusion
-Both Island AI and Instructor play distinct roles in AI-driven development. Whether it's handling real-time data streams in the browser or performing complex data extraction on the server, these tools offer flexibility and power to build sophisticated, responsive, and user-centric applications.
-
-By understanding the unique strengths and use cases of each tool, developers can make informed decisions on how best to integrate them into their AI-driven projects, maximizing efficiency and user engagement.
\ No newline at end of file
diff --git a/apps/www/src/docs/overview.mdx b/apps/www/src/docs/overview.mdx
deleted file mode 100644
index 0391045..0000000
--- a/apps/www/src/docs/overview.mdx
+++ /dev/null
@@ -1,25 +0,0 @@
-# Introduction to Island AI
-
-Island AI is a collection of TypeScript tools designed to enhance the way developers create user interfaces for AI applications. Moving beyond traditional chat interfaces, it offers more flexibility and power for handling AI-driven interactions.
-
-## Why Island AI?
-The idea for Island AI came from the limitations of regular chat interfaces in AI applications. While chat interfaces are familiar, they often limit how we can interact with AI. Island AI aims to change that by allowing more complex and interactive UIs, especially when dealing with real-time data and AI responses.
-
-## Key Features
- - **Handles Complex Data**: Island AI makes it easier to work with structured data in real-time, which is often a challenge in AI applications.
- - **For Modern Web Apps**: With a focus on React, Island AI integrates smoothly into modern web applications, providing tools that are easy to use for developers.
- - **Improves User Experience**: By enabling more dynamic interactions, Island AI helps create interfaces that are more engaging and responsive.
-
-## What's Inside Island AI?
-**Island AI includes**:
-
-- Tools for managing structured data with Zod schemas.
-- A JSON streaming parser for handling real-time data.
-- React hooks for easy integration into web applications.
-
-## Learn More
-For more on the background and motivations behind Island AI, you can read my detailed article, ["Breaking free from the chat box" here](https://www.hack.dance/thoughts/break-free-from-chat-the-box).
-
-
----
-Island AI is about giving developers the tools to build better AI-driven interfaces. It's about making it easier to handle complex, real-time data and create more engaging user experiences.
\ No newline at end of file
diff --git a/apps/www/src/docs/stream-hooks-api.mdx b/apps/www/src/docs/stream-hooks-api.mdx
deleted file mode 100644
index b5a2a7d..0000000
--- a/apps/www/src/docs/stream-hooks-api.mdx
+++ /dev/null
@@ -1,51 +0,0 @@
-## API Reference
-
-### `useStream`
-
-A custom React hook for managing and interacting with a data stream.
-
-#### Properties
-
-```typescript
-useStream({ onBeforeStart, onStop }: UseStreamProps)
-```
-
-| Property | Type | Required | Description |
-|----------------|----------|----------|-------------------------------------------------|
-| onBeforeStart | Function | No | Callback function invoked before the stream starts. |
-| onStop | Function | No | Callback function invoked when the stream stops. |
-
-#### Returns
-
-| Property | Type | Description |
-|-------------|------------|-------------------------------------------------|
-| startStream | Function | Function to start the stream. |
-| stopStream | Function | Function to stop the stream. |
-
-### `useJsonStream`
-
-Extends `useStream` to handle JSON streaming, with parsing based on a provided Zod schema.
-
-#### Properties
-
-```typescript
-useJsonStream({ onReceive, onEnd, schema, onBeforeStart, onStop, defaultData }: UseJsonStreamProps)
-```
-
-| Property | Type | Required | Description |
-|----------------|----------------|----------|-----------------------------------------------------|
-| onReceive | Function | No | Callback invoked with each piece of received data. |
-| onEnd | Function | No | Callback invoked when the stream ends. |
-| schema | z.AnyZodObject | Yes | Zod schema for validating and parsing the JSON data.|
-| onBeforeStart | Function | No | Callback function invoked before the stream starts. |
-| onStop | Function | No | Callback function invoked when the stream stops. |
-| defaultData | Object | No | Default data to use before any stream data arrives. |
-
-#### Returns
-
-| Property | Type | Description |
-|-------------|------------|---------------------------------------------------|
-| startStream | Function | Function to start the stream. |
-| stopStream | Function | Function to stop the stream. |
-| data | Object | The latest piece of parsed data from the stream. |
-| loading | boolean | Indicates whether the stream is currently active. |
diff --git a/apps/www/src/docs/stream-hooks-getting-started.mdx b/apps/www/src/docs/stream-hooks-getting-started.mdx
deleted file mode 100644
index 3ad604a..0000000
--- a/apps/www/src/docs/stream-hooks-getting-started.mdx
+++ /dev/null
@@ -1,90 +0,0 @@
-## Getting Started
-
-### Installation
-
-To start using `stream-hooks` in your React project, you can install it using your preferred package manager. Below are the commands for npm, pnpm, and yarn.
-
-#### With npm
-```bash
-npm install stream-hooks zod zod-stream
-```
-
-#### With pnpm
-```bash
-pnpm add stream-hooks zod zod-stream
-```
-
-#### With bun
-```bash
-bun add stream-hooks zod zod-stream
-```
-
-### Basic Setup
-
-Once `stream-hooks` is installed in your project, you can start using the hooks in your React components. Ensure you have React set up in your project as `stream-hooks` is designed to work within a React environment.
-
-#### Using `useStream`
-
-```typescript
-import React from 'react';
-import { useStream } from 'stream-hooks';
-
-const MyComponent = () => {
- const { startStream, stopStream } = useStream({
- onBeforeStart: () => console.log('Stream is about to start'),
- onStop: () => console.log('Stream has stopped')
- });
-
- // Start and stop stream based on component lifecycle or user interactions
- // ...
-
- return (
-
-
-
-
- );
-};
-
-export default MyComponent;
-```
-
-#### Using `useJsonStream`
-
-```typescript
-import React from 'react';
-import { useJsonStream } from 'stream-hooks';
-import { z } from 'zod';
-
-const MyJsonComponent = () => {
- const schema = z.object({
- message: z.string(),
- });
-
- const {
- data,
- startStream,
- stopStream,
- loading
- } = useJsonStream({
- schema,
- onBeforeStart: () => console.log('JSON stream is about to start'),
- onStop: () => console.log('JSON stream has stopped'),
- onReceive: (json) => console.log('Received data:', json)
- });
-
- // Start and stop stream based on component lifecycle or user interactions
- // ...
-
- return (
-
-
-
- {loading &&
Loading...
}
-
{JSON.stringify(data, null, 2)}
-
- );
-};
-
-export default MyJsonComponent;
-```
diff --git a/apps/www/src/docs/stream-hooks.mdx b/apps/www/src/docs/stream-hooks.mdx
deleted file mode 100644
index a3a8d6a..0000000
--- a/apps/www/src/docs/stream-hooks.mdx
+++ /dev/null
@@ -1,13 +0,0 @@
-# stream-hooks
-
-## Introduction
-
-**stream-hooks** is a React hooks library designed to simplify the integration and management of streaming data in web applications. This package provides custom hooks that abstract the complexities of handling streaming data, making it easier for developers to focus on building responsive and dynamic UI.
-
-### Key Features
-
- - **Simplified Stream Management**: With useStream, manage the lifecycle of streaming data, including starting and stopping streams, with ease.
- - **JSON Streaming Made Easy**: useJsonStream extends useStream, adding the capability to parse streaming JSON data using Zod schemas.
- - **Seamless Integration with React**: Designed specifically for React, these hooks integrate smoothly into your React components.
- - **Real-time Data Handling**: Perfect for applications requiring real-time data updates, such as dashboards, live feeds, or interactive AI-driven UIs.
-
diff --git a/apps/www/src/docs/zod-stream-api.mdx b/apps/www/src/docs/zod-stream-api.mdx
deleted file mode 100644
index b38f225..0000000
--- a/apps/www/src/docs/zod-stream-api.mdx
+++ /dev/null
@@ -1,59 +0,0 @@
-## API Reference
-
-`zod-stream` offers various classes and functions to handle structured JSON streaming. Below is the detailed API reference.
-
-### ZodStream
-
-```typescript
-import ZodStream from "zod-stream"
-
-const zodstream = new ZodStream(config)
-```
-
-#### Constructor
-
-```typescript
-constructor(config?: ClientConfig)
-```
-
-##### ClientConfig
-
-| Property | Type | Description | Default |
-|----------|---------|-----------------------------------------------|---------|
-| debug | boolean | Enables debug mode for detailed logging. | false |
-
-#### Methods
-
-##### `chatCompletionStream`
-
-```typescript
-chatCompletionStream(params: StructredStreamCompletionParams): Promise>, void, unknown>>
-```
-
-##### StructredStreamCompletionParams
-
-| Property | Type | Description |
-|-----------------|-----------------------|-----------------------------------------------------|
-| completionPromise | Function | A function that returns a promise resolving to a stream. |
-| data | any | Data to be sent in the stream request. |
-| response_model | ResponseModel\ | The Zod schema model for the stream response. |
-
-##### ResponseModel
-
-| Property | Type | Description |
-|-----------------|-----------------------|-----------------------------------------------------|
-| name | string | Name of the response model. |
-| schema | z.AnyZodObject | The Zod schema for validation. |
-| description | string | A description of the response model. |
-
-### OAIStream
-
-```typescript
-OAIStream({ res }: OaiStreamArgs): ReadableStream
-```
-
-##### OaiStreamArgs
-
-| Property | Type | Description |
-|-----------------|-----------------------|-----------------------------------------------------|
-| res | Stream | The stream of data from OpenAI or AnyScale. |
diff --git a/apps/www/src/docs/zod-stream-examples-basic.mdx b/apps/www/src/docs/zod-stream-examples-basic.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/apps/www/src/docs/zod-stream-examples-next.mdx b/apps/www/src/docs/zod-stream-examples-next.mdx
deleted file mode 100644
index e69de29..0000000
diff --git a/apps/www/src/docs/zod-stream-getting-started.mdx b/apps/www/src/docs/zod-stream-getting-started.mdx
deleted file mode 100644
index 69809a8..0000000
--- a/apps/www/src/docs/zod-stream-getting-started.mdx
+++ /dev/null
@@ -1,117 +0,0 @@
-## Getting Started
-
-### Installation
-
-`zod-stream` can be easily installed using your preferred package manager. Below are the commands for pnpm, npm, and bun.
-
-#### With bun
-```bash
-$ bun add zod-stream zod openai
-```
-
-#### With pnpm
-```bash
-$ pnpm add zod-stream zod openai
-```
-
-#### With npm
-```bash
-$ npm install zod-stream zod openai
-```
-
-
-### Basic Setup
-
-To start using `zod-stream` in your project, follow these simple steps:
-
-1. **Define a response model**
-
- Import and initialize the necessary modules from zod-stream, zod, and openai.
-
- ```typescript
- import { z } from "zod";
-
- export const my_response_model = {
- schema: z.object({
- content: z.string()
- }),
- name: "bot response json"
- }
- ```
-2. **Create a structured LLM response using zod and zod-stream**
-
- Ensure that your environment variables are properly configured, especially if you are interacting with external services like OpenAI.
- ```typescript
- process.env["OPENAI_API_KEY"] = "your-openai-api-key"; // Replace with your OpenAI API key
- process.env["OPENAI_ORG_ID"] = "your-openai-org-id"; // Replace with your OpenAI Organization ID (if applicable)
- ```
-
- Import and initialize the necessary modules from zod-stream, zod, and openai, then pass your response model to the LLM provider using the `withResponseModel` utility.
- ```typescript
- import { withResponseModel } from "zod-stream";
- import OpenAI from "openai";
-
- import { my_response_model } from "./my_response_model"
-
- const openAI = new OpenAI({
- apiKey: process.env["OPENAI_API_KEY"],
- organization: process.env["OPENAI_ORG_ID"]
- });
-
-
- // build completion params for the selected mode.
- const params = withResponseModel({
- response_model: my_response_model,
- params: {
- messages,
- model: "gpt-4"
- },
- mode: "TOOLS"
- })
-
- // make a completion call with your generated params
- const extractionStream = await oai.chat.completions.create({
- ...params,
- stream: true
- })
-
-
- // convert the default SSE response to a readable stream and then return as api response or pass elsewhere.
- const my_stream = OAIStream({
- res: extractionStream
- })
- ```
-
-3. **Read the partial streaming response from the stream**
-
- ```typescript
- import ZodStreamfrom "zod-stream";
- import OpenAI from "openai";
-
- import { my_response_model } from "./my_response_model"
-
- const zodstream = new ZodStream()
-
- const stream = await zodstream.create({
- completionPromise: async () => {
- // a promise that returns the stream created in step 2. This could be a fetch call or a promise that resolves the same way.
-
- const response = fetch("/api/get-stream", {
- body: JSON.stringify({ messages: [] }),
- method: "POST"
- })
-
- return response.body
- },
- // this schema should match the response model expected by the stream
- response_model: my_response_model
- })
-
- for await (const chunk of stream) {
- console.log(chunk) // safe to parse partial json
- }
- ```
-
-
-This setup will prepare your application to handle structured LLM response streams effectively using zod-stream.
-For more advanced configurations and detailed usage, refer to the Usage and API Reference sections.
\ No newline at end of file
diff --git a/apps/www/src/docs/zod-stream.mdx b/apps/www/src/docs/zod-stream.mdx
deleted file mode 100644
index f9a67e1..0000000
--- a/apps/www/src/docs/zod-stream.mdx
+++ /dev/null
@@ -1,18 +0,0 @@
-# zod-stream
-
-## Introduction
-
-### Overview
-`zod-stream` is a powerful TypeScript toolkit designed for building dynamic, AI-generated UI. It provides a seamless interface for parsing structured, streaming JSON data from OpenAI or AnyScale, ensuring immediate safety and readability. Leveraging `Schema-Stream` for efficient parsing, `zod-stream` is ideal for real-time applications requiring structured LLM response streams.
-
-### Key Features
- - **Efficient JSON Parsing**: Utilizes `Schema-Stream` for fast and efficient parsing of streaming JSON data.
- - **Real-Time Data Validation**: Integrates with Zod for on-the-fly validation of data, ensuring that the streams are structured and conform to predefined schemas.
- - **OpenAI Integration**: Seamlessly works with OpenAI, making it perfect for applications using AI-generated content.
- - **AnyScale Compatibility**: Designed to be compatible with AnyScale, enhancing its versatility in various streaming contexts.
- - **Dynamic AI-Generated UI**: Facilitates the creation of dynamic UI that are powered by AI, allowing for real-time updates and interactions.
- - **TypeScript Support**: Built with TypeScript, offering strong typing and making it a natural fit for TypeScript-based projects.
- - **Error Handling**: Robust error handling capabilities to ensure reliability and ease of debugging in production environments.
- - **Customizable and Extendable**: Offers flexibility to be customized and extended to suit specific application needs.
-
-These features make `zod-stream` an ideal choice for developers looking to integrate structured, streaming JSON data from AI sources into their applications, especially those focusing on dynamic and interactive UIs.
\ No newline at end of file
diff --git a/apps/www/src/lib/metadata.ts b/apps/www/src/lib/metadata.ts
new file mode 100644
index 0000000..bc3c1ab
--- /dev/null
+++ b/apps/www/src/lib/metadata.ts
@@ -0,0 +1,8 @@
+import { createMetadataImage } from "fumadocs-core/server"
+
+import { source } from "@/lib/source"
+
+export const metadataImage = createMetadataImage({
+ imageRoute: "/docs-og",
+ source
+})
diff --git a/apps/www/src/lib/source.ts b/apps/www/src/lib/source.ts
new file mode 100644
index 0000000..2ef677d
--- /dev/null
+++ b/apps/www/src/lib/source.ts
@@ -0,0 +1,8 @@
+import { docs } from "@/../.source"
+import { loader } from "fumadocs-core/source"
+import { createMDXSource } from "fumadocs-mdx"
+
+export const source = loader({
+ baseUrl: "/docs",
+ source: createMDXSource(docs, [])
+})
diff --git a/apps/www/tailwind.config.ts b/apps/www/tailwind.config.ts
index e2903af..4949a51 100644
--- a/apps/www/tailwind.config.ts
+++ b/apps/www/tailwind.config.ts
@@ -1,13 +1,15 @@
import sharedConfig from "@repo/tailwind-config/tailwind.config"
+import { createPreset } from "fumadocs-ui/tailwind-plugin"
import type { Config } from "tailwindcss"
const config: Pick = {
content: [
- "../../packages/ui/dist/**/*.{mjs,js,ts,jsx,tsx}",
- "./**/*.{js,ts,jsx,tsx}",
- "./pages/**/*.{js,ts,jsx,tsx}"
+ "../../packages/ui/src/**/*.{mjs,js,ts,jsx,tsx}",
+ "../../node_modules/fumadocs-ui/dist/**/*.js",
+ "./src/**/*.{js,ts,jsx,tsx}",
+ "./src/app/**/*.{js,ts,jsx,tsx}"
],
- presets: [sharedConfig]
+ presets: [sharedConfig, createPreset()]
}
export default config
diff --git a/apps/www/tsconfig.json b/apps/www/tsconfig.json
index 5fc97e3..9e9daf9 100644
--- a/apps/www/tsconfig.json
+++ b/apps/www/tsconfig.json
@@ -7,7 +7,8 @@
}
],
"paths": {
- "@/*": ["./src/*"]
+ "@/*": ["./src/*"],
+ "@ui/*": ["../../packages/ui/src/*"]
},
"baseUrl": ".",
"declaration": false,
@@ -20,10 +21,12 @@
"include": [
"next-env.d.ts",
"next.config.js",
- "**/*.ts",
- "**/*.tsx",
+ "src/**/*.ts",
+ "src/**/*.tsx",
".next/types/**/*.ts",
- "postcss.config.js"
+ "postcss.config.js",
+ "tailwind.config.ts"
],
"exclude": ["node_modules"]
}
+
\ No newline at end of file
diff --git a/apps/www/tsconfig.lint.json b/apps/www/tsconfig.lint.json
index 5fc97e3..026e0e1 100644
--- a/apps/www/tsconfig.lint.json
+++ b/apps/www/tsconfig.lint.json
@@ -7,7 +7,8 @@
}
],
"paths": {
- "@/*": ["./src/*"]
+ "@/*": ["./src/*"],
+ "@ui/*": ["../../packages/ui/src/*"]
},
"baseUrl": ".",
"declaration": false,
@@ -20,10 +21,11 @@
"include": [
"next-env.d.ts",
"next.config.js",
- "**/*.ts",
- "**/*.tsx",
+ "src/**/*.ts",
+ "src/**/*.tsx",
".next/types/**/*.ts",
- "postcss.config.js"
+ "postcss.config.js",
+ "tailwind.config.ts"
],
"exclude": ["node_modules"]
}
diff --git a/bun.lockb b/bun.lockb
index 80fdd9e..838b317 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index 7eb6028..e2d08f9 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
"scripts": {
"build": "turbo run build --no-daemon --concurrency=11",
"dev": "turbo dev --no-daemon --concurrency=11",
+ "docs": "turbo dev --filter=docs",
"lint": "turbo lint --concurrency=11",
"type-check": "turbo type-check --concurrency=11",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
@@ -11,7 +12,9 @@
"start": "turbo next start",
"changeset": "changeset",
"version-packages": "changeset version",
- "publish-packages": "turbo run build --filter='./public-packages/*' && changeset publish"
+ "publish-packages": "turbo run build --filter='./public-packages/*' && changeset publish",
+ "sync-ls": "syncpack list-mismatches",
+ "sync-up": "syncpack fix-mismatches"
},
"devDependencies": {
"@changesets/changelog-github": "latest",
@@ -22,6 +25,7 @@
"@types/bun": "^1.0.1",
"husky": "^8.0.3",
"prettier": "^3.1.1",
+ "syncpack": "^12.4.0",
"turbo": "latest"
},
"engines": {
@@ -32,6 +36,5 @@
"apps/*",
"packages/*",
"public-packages/*"
- ],
- "dependencies": {}
+ ]
}
diff --git a/packages/constants/.eslintrc.js b/packages/constants/.eslintrc.js
deleted file mode 100644
index bce31ee..0000000
--- a/packages/constants/.eslintrc.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const { resolve } = require("node:path")
-
-const project = resolve(__dirname, "tsconfig.lint.json")
-
-/** @type {import("eslint").Linter.Config} */
-module.exports = {
- root: true,
- extends: ["@repo/eslint-config/react-internal.js"],
- parser: "@typescript-eslint/parser",
- parserOptions: {
- project
- },
- overrides: [
- {
- extends: ["plugin:@typescript-eslint/disable-type-checked"],
- files: ["./**/*.js", "*.js"]
- }
- ],
- settings: {
- tailwindcss: {
- callees: ["cn"],
- config: "tailwind.config.js"
- }
- }
-}
diff --git a/packages/constants/package.json b/packages/constants/package.json
deleted file mode 100644
index aefe7b0..0000000
--- a/packages/constants/package.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "@repo/constants",
- "version": "0.0.1",
- "private": true,
- "main": "./dist/index.js",
- "module": "./dist/index.mjs",
- "types": "./dist/index.d.ts",
- "license": "MIT",
- "exports": {
- ".": "./dist/index.mjs",
- "./types/api": "./dist/types/api.mjs"
- },
- "scripts": {
- "build": "tsup",
- "dev": "tsup --watch",
- "lint": "eslint src/",
- "type-check": "tsc --noEmit",
- "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
- },
- "devDependencies": {
- "@repo/eslint-config": "workspace:*",
- "@repo/tailwind-config": "workspace:*",
- "@repo/typescript-config": "workspace:*",
- "@turbo/gen": "^1.10.12",
- "@types/node": "^20.5.2",
- "@types/eslint": "^8.44.7",
- "@types/react": "^18.2.18",
- "@types/react-dom": "^18.2.18",
- "autoprefixer": "^10.4.16",
- "eslint": "^8.53.0",
- "typescript": "^5.2.2",
- "ramda": "^0.29.0",
- "zod": "^3.23.3"
- },
- "peerDependencies": {},
- "dependencies": {
- "tsup": "^8.0.1"
- }
-}
diff --git a/packages/constants/src/index.ts b/packages/constants/src/index.ts
deleted file mode 100644
index 32984dd..0000000
--- a/packages/constants/src/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const YO = "yo"
diff --git a/packages/constants/src/types/api.ts b/packages/constants/src/types/api.ts
deleted file mode 100644
index f2d0b5c..0000000
--- a/packages/constants/src/types/api.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const dude = "yo"
diff --git a/packages/constants/tsconfig.json b/packages/constants/tsconfig.json
deleted file mode 100644
index e01871f..0000000
--- a/packages/constants/tsconfig.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "extends": "@repo/typescript-config/react-library.json",
- "compilerOptions": {
- "outDir": "dist",
- "paths": {
- "@/*": ["./src/*"]
- },
- "baseUrl": "."
- },
- "include": ["src", "turbo", "tsup.config.ts"],
- "exclude": ["node_modules", "dist"]
-}
diff --git a/packages/constants/tsconfig.lint.json b/packages/constants/tsconfig.lint.json
deleted file mode 100644
index e01871f..0000000
--- a/packages/constants/tsconfig.lint.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "extends": "@repo/typescript-config/react-library.json",
- "compilerOptions": {
- "outDir": "dist",
- "paths": {
- "@/*": ["./src/*"]
- },
- "baseUrl": "."
- },
- "include": ["src", "turbo", "tsup.config.ts"],
- "exclude": ["node_modules", "dist"]
-}
diff --git a/packages/constants/tsup.config.ts b/packages/constants/tsup.config.ts
deleted file mode 100644
index 4efa68e..0000000
--- a/packages/constants/tsup.config.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { defineConfig } from "tsup"
-
-export default defineConfig(options => {
- return {
- splitting: true,
- entry: ["src/**/*.{ts,tsx}"],
- format: ["esm"],
- dts: true,
- minify: true,
- clean: true,
- ...options
- }
-})
diff --git a/packages/constants/turbo.json b/packages/constants/turbo.json
deleted file mode 100644
index 59c7384..0000000
--- a/packages/constants/turbo.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "$schema": "https://turbo.build/schema.json",
- "extends": ["//"],
- "pipeline": {
- "build": {
- "outputs": ["dist/**"]
- }
- }
-}
diff --git a/packages/tailwind-config/package.json b/packages/tailwind-config/package.json
index 3ea7514..4debdf7 100644
--- a/packages/tailwind-config/package.json
+++ b/packages/tailwind-config/package.json
@@ -9,17 +9,17 @@
"dependencies": {
"@radix-ui/colors": "^1.0.1",
"@tailwindcss/typography": "^0.5.9",
- "tailwindcss-animate": "^1.0.5",
+ "tailwindcss-animate": "^1.0.6",
"postcss-100vh-fix": "^1.0.2",
"windy-radix-palette": "^0.6.1"
},
"devDependencies": {
- "autoprefixer": "^10.4.13",
+ "autoprefixer": "^10.4.16",
"postcss": "^8.4.25",
- "tailwindcss": "^3.3.2",
- "typescript": "^5.2.2"
+ "tailwindcss": "^3.3.5",
+ "typescript": "^5.3.3"
},
"peerDependencies": {
- "tailwindcss": "^3.2.2"
+ "tailwindcss": "^3.3.5"
}
}
diff --git a/packages/ui/package.json b/packages/ui/package.json
index f7145b6..b8ad3fb 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -2,106 +2,104 @@
"name": "@repo/ui",
"version": "0.0.1",
"private": true,
- "main": "./dist/index.js",
- "module": "./dist/index.mjs",
- "types": "./dist/index.d.ts",
+ "type": "module",
"license": "MIT",
"exports": {
- "./components/*": "./dist/components/*.mjs",
- "./components/ui/*": "./dist/components/ui/*.mjs",
- "./components/table": "./dist/components/table/index.mjs",
- "./components/table/*": "./dist/components/table/*.mjs",
- "./components/primitives/*": "./dist/components/primitives/*.mjs",
- "./hooks/*": "./dist/hooks/*.mjs",
- "./styles.css": "./dist/index.css"
+ "./components/*": "./src/components/*.tsx",
+ "./components/ui/*": "./src/components/ui/*.tsx",
+ "./components/table": "./src/components/table/index.tsx",
+ "./components/table/*": "./src/components/table/*.tsx",
+ "./components/primitives/*": "./src/components/primitives/*.tsx",
+ "./hooks/*": "./src/hooks/*.ts"
},
"scripts": {
- "build": "tailwindcss -i ./src/styles/globals.css -o dist/index.css && tsup",
- "dev": "tailwindcss -i ./src/styles/globals.css -o ./dist/index.css --watch & tsup --watch",
- "lint": "eslint src/",
+ "lint:check": "TIMING=1 eslint src --max-warnings=0",
+ "lint:fix": "eslint --fix src",
"type-check": "tsc --noEmit",
"generate:component": "turbo gen react-component",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
},
"devDependencies": {
"@repo/eslint-config": "workspace:*",
- "@repo/tailwind-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
- "@turbo/gen": "^1.11.3",
- "@types/node": "^20.10.6",
- "@types/eslint": "^8.56.1",
- "@types/react": "^18.2.46",
- "@types/react-dom": "^18.2.18",
- "autoprefixer": "^10.4.16",
- "eslint": "^8.53.0",
- "react": "^18.2.0",
- "typescript": "^5.2.2",
- "tailwindcss": "^3.3.5",
- "@hookform/resolvers": "^3.1.1",
- "@mux/mux-player": "latest",
- "@mux/mux-player-react": "^2.2.0",
- "@qdrant/js-client-rest": "^1.6.0",
- "@radix-ui/react-accordion": "^1.1.2",
- "@radix-ui/react-alert-dialog": "^1.0.4",
- "@radix-ui/react-aspect-ratio": "^1.0.3",
- "@radix-ui/react-avatar": "^1.0.3",
- "@radix-ui/react-checkbox": "^1.0.4",
- "@radix-ui/react-collapsible": "^1.0.3",
- "@radix-ui/react-context-menu": "^2.1.4",
- "@radix-ui/react-dialog": "^1.0.4",
- "@radix-ui/react-dropdown-menu": "^2.0.5",
- "@radix-ui/react-hover-card": "^1.0.6",
+ "@repo/tailwind-config": "workspace:*",
+ "autoprefixer": "^10.4.20",
+ "tailwindcss": "^3.4.14"
+ },
+ "peerDependencies": {
+ "react": "19.0.0-rc-66855b96-20241106",
+ "react-dom": "19.0.0-rc-66855b96-20241106",
+ "lucide-react": "*",
+ "next": "15.0.3"
+ },
+ "dependencies": {
+ "@hookform/resolvers": "^3.9.1",
+ "@mynaui/icons-react": "latest",
+ "@radix-ui/react-accessible-icon": "^1.1.0",
+ "@radix-ui/react-accordion": "^1.2.1",
+ "@radix-ui/react-alert-dialog": "^1.1.2",
+ "@radix-ui/react-aspect-ratio": "^1.1.0",
+ "@radix-ui/react-avatar": "^1.1.1",
+ "@radix-ui/react-checkbox": "^1.1.2",
+ "@radix-ui/react-collapsible": "^1.1.1",
+ "@radix-ui/react-context-menu": "^2.2.2",
+ "@radix-ui/react-dialog": "^1.1.2",
+ "@radix-ui/react-dropdown-menu": "^2.1.2",
+ "@radix-ui/react-hover-card": "^1.1.2",
"@radix-ui/react-icons": "^1.3.0",
- "@radix-ui/react-label": "^2.0.2",
- "@radix-ui/react-menubar": "^1.0.3",
- "@radix-ui/react-navigation-menu": "^1.1.3",
- "@radix-ui/react-popover": "^1.0.6",
- "@radix-ui/react-progress": "^1.0.3",
- "@radix-ui/react-radio-group": "^1.1.3",
- "@radix-ui/react-scroll-area": "^1.0.4",
- "@radix-ui/react-select": "^1.2.2",
- "@radix-ui/react-separator": "^1.0.3",
- "@radix-ui/react-slider": "^1.1.2",
- "@radix-ui/react-slot": "^1.0.2",
- "@radix-ui/react-switch": "^1.0.3",
- "@radix-ui/react-tabs": "^1.0.4",
- "@radix-ui/react-toast": "^1.1.4",
- "@radix-ui/react-toggle": "^1.0.3",
- "@radix-ui/react-tooltip": "^1.0.6",
+ "@radix-ui/react-label": "^2.1.0",
+ "@radix-ui/react-menubar": "^1.1.2",
+ "@radix-ui/react-navigation-menu": "^1.2.1",
+ "@radix-ui/react-popover": "^1.1.2",
+ "@radix-ui/react-progress": "^1.1.0",
+ "@radix-ui/react-radio-group": "^1.2.1",
+ "@radix-ui/react-scroll-area": "^1.2.1",
+ "@radix-ui/react-select": "^2.1.2",
+ "@radix-ui/react-separator": "^1.1.0",
+ "@radix-ui/react-slider": "^1.2.1",
+ "@radix-ui/react-slot": "^1.1.0",
+ "@radix-ui/react-switch": "^1.1.1",
+ "@radix-ui/react-tabs": "^1.1.1",
+ "@radix-ui/react-toast": "^1.2.2",
+ "@radix-ui/react-toggle": "^1.1.0",
+ "@radix-ui/react-toggle-group": "^1.1.0",
+ "@radix-ui/react-tooltip": "^1.1.4",
"@tanstack/react-table": "^8.9.3",
- "@types/three": "^0.155.0",
+ "@uiw/react-color": "^2.0.5",
"avvvatars-react": "^0.4.2",
"class-variance-authority": "^0.7.0",
- "clsx": "^1.2.1",
- "cmdk": "^0.2.0",
- "date-fns": "^2.30.0",
- "framer-motion": "^10.12.18",
- "ramda": "^0.29.0",
- "react-day-picker": "^8.8.0",
- "react-dom": "18.2.0",
+ "clsx": "^2.1.0",
+ "cmdk": "1.0.0",
+ "date-fns": "^4.1.0",
+ "embla-carousel-react": "^8.5.1",
+ "motion": "^12.0.0-alpha.2",
+ "input-otp": "^1.4.1",
+ "next-themes": "^0.4.3",
+ "ramda": "*",
+ "react-day-picker": "8.10.1",
+ "react": "19.0.0-rc-66855b96-20241106",
+ "react-dom": "19.0.0-rc-66855b96-20241106",
"react-email": "latest",
- "react-hook-form": "^7.45.2",
+ "react-hook-form": "^7.53.2",
"react-intersection-observer": "^9.5.2",
"react-markdown": "^8.0.7",
+ "react-resizable-panels": "^2.1.7",
"reactflow": "^11.9.4",
+ "recharts": "^2.13.3",
"rehype-highlight": "^6.0.0",
"resend": "latest",
"simplex-noise": "^4.0.1",
- "sonner": "latest",
+ "sonner": "*",
"svix": "^1.13.0",
- "tailwind-merge": "^1.13.2",
+ "tailwind-merge": "^2.2.2",
+ "tailwindcss-animate": "^1.0.7",
"tippy.js": "^6.3.7",
+ "tsup": "^8.0.1",
"use-debounce": "^9.0.4",
- "vaul": "^0.7.9",
- "zod": "^3.23.3"
- },
- "peerDependencies": {
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "lucide-react": "latest"
+ "vaul": "*",
+ "zod": "^3.23.8"
},
- "dependencies": {
- "@uiw/react-color": "^2.0.5",
- "tsup": "^8.0.1"
+ "overrides": {
+ "react-is": "^19.0.0-rc-69d4b800-20241021"
}
}
diff --git a/packages/ui/src/components/animated-border-wrapper.tsx b/packages/ui/src/components/animated-border-wrapper.tsx
deleted file mode 100644
index be8d48e..0000000
--- a/packages/ui/src/components/animated-border-wrapper.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import React from "react"
-
-import { cn } from "@/lib/utils"
-
-export const AnimatedBorderWrapper = ({
- children,
- enabled,
- strokeWidth = 3,
- className
-}: {
- children: React.ReactNode
- enabled: boolean
- strokeWidth?: number
- className?: string
-}) => {
- if (!enabled) return <>{children}>
-
- return (
-
- Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
-
{table.getPageCount() > 1 && (
-
- table.setPageIndex(0)}
- disabled={!table.getCanPreviousPage()}
- >
- Go to first page
-
-
- table.previousPage()}
- disabled={!table.getCanPreviousPage()}
- >
- Go to previous page
-
-
- table.nextPage()}
- disabled={!table.getCanNextPage()}
- >
- Go to next page
-
-
- table.setPageIndex(table.getPageCount() - 1)}
- disabled={!table.getCanNextPage()}
- >
- Go to last page
-
-
-
+ table.setPageIndex(0)}
+ disabled={!table.getCanPreviousPage()}
+ >
+ Go to first page
+
+
+ table.previousPage()}
+ disabled={!table.getCanPreviousPage()}
+ >
+ Go to previous page
+
+
+ table.nextPage()}
+ disabled={!table.getCanNextPage()}
+ >
+ Go to next page
+
+
+ table.setPageIndex(table.getPageCount() - 1)}
+ disabled={!table.getCanNextPage()}
+ >
+ Go to last page
+
+
+