From 87e2b7d346d1acecf5a48eb0fc562283fe5c74ce Mon Sep 17 00:00:00 2001 From: Andres J Date: Sat, 7 Feb 2026 16:07:16 -0600 Subject: [PATCH] fix(docs): corregir rutas relativas seccionales (evitar doble segmento bajo /
/) --- .../content/docs/backend/getting-started.md | 6 +- apps/docs/src/content/docs/backend/index.mdx | 271 +++++++++--------- .../src/content/docs/backend/installation.md | 8 +- .../src/content/docs/react/getting-started.md | 17 +- apps/docs/src/content/docs/react/index.mdx | 8 +- .../src/content/docs/react/installation.md | 16 +- .../src/content/docs/solid/getting-started.md | 6 +- apps/docs/src/content/docs/solid/index.mdx | 8 +- .../src/content/docs/solid/installation.md | 8 +- .../content/docs/universal/getting-started.md | 6 +- .../docs/src/content/docs/universal/index.mdx | 6 +- 11 files changed, 180 insertions(+), 180 deletions(-) diff --git a/apps/docs/src/content/docs/backend/getting-started.md b/apps/docs/src/content/docs/backend/getting-started.md index 6d97ed2b..87baa982 100644 --- a/apps/docs/src/content/docs/backend/getting-started.md +++ b/apps/docs/src/content/docs/backend/getting-started.md @@ -514,9 +514,9 @@ You should see: Now that you have the basics set up, explore the specific packages: -- [Node Better Auth](backend/packages/node-better-auth/) - Learn authentication patterns -- [Node Auth App](backend/packages/node-auth-app/) - Explore the complete auth service -- [Backend Reference](backend/reference/) - Dive into the API documentation +- [Node Better Auth](packages/node-better-auth/) - Learn authentication patterns +- [Node Auth App](packages/node-auth-app/) - Explore the complete auth service +- [Backend Reference](reference/) - Dive into the API documentation ## Common Patterns diff --git a/apps/docs/src/content/docs/backend/index.mdx b/apps/docs/src/content/docs/backend/index.mdx index 778502c9..f8a57d7e 100644 --- a/apps/docs/src/content/docs/backend/index.mdx +++ b/apps/docs/src/content/docs/backend/index.mdx @@ -3,7 +3,7 @@ title: Backend Integration description: Effect integration packages for Node.js backend applications --- -import { Card, CardGrid } from '@astrojs/starlight/components'; +import { Card, CardGrid } from "@astrojs/starlight/components"; # Backend Integration @@ -13,15 +13,15 @@ Effectify provides powerful Node.js backend integrations that combine the robust - Effect integration with better-auth for Node.js applications. Provides type-safe authentication with Effect's error handling and composability. - - [Learn more →](backend/packages/node-better-auth/) + Effect integration with better-auth for Node.js applications. Provides + type-safe authentication with Effect's error handling and composability. + [Learn more →](packages/node-better-auth/) - + - Complete authentication server application built with Effect, better-auth, and modern Node.js patterns. Ready-to-deploy auth service. - - [Learn more →](backend/packages/node-auth-app/) + Complete authentication server application built with Effect, better-auth, + and modern Node.js patterns. Ready-to-deploy auth service. [Learn more + →](packages/node-auth-app/) @@ -30,9 +30,8 @@ Effectify provides powerful Node.js backend integrations that combine the robust Ready to start building backend services with Effectify? Check out our getting started guide to set up your first Node.js project with Effect. - Get up and running with Effectify in your Node.js backend application in minutes. - - [Get Started →](backend/getting-started/) + Get up and running with Effectify in your Node.js backend application in + minutes. [Get Started →](getting-started/) ## Key Features @@ -52,48 +51,52 @@ Effectify backend packages follow a layered architecture pattern: // Domain Layer - Pure business logic const authenticateUser = (credentials: LoginCredentials) => Effect.gen(function* () { - const user = yield* UserRepository.findByEmail(credentials.email) - const isValid = yield* PasswordService.verify(credentials.password, user.hashedPassword) - + const user = yield* UserRepository.findByEmail(credentials.email); + const isValid = yield* PasswordService.verify( + credentials.password, + user.hashedPassword, + ); + if (!isValid) { - yield* Effect.fail(new AuthenticationError('Invalid credentials')) + yield* Effect.fail(new AuthenticationError("Invalid credentials")); } - - return user - }) + + return user; + }); // Service Layer - Application services const AuthService = { login: (credentials: LoginCredentials) => Effect.gen(function* () { - const user = yield* authenticateUser(credentials) - const token = yield* TokenService.generate(user.id) - const session = yield* SessionService.create(user.id, token) - - return { user, token, session } - }) -} + const user = yield* authenticateUser(credentials); + const token = yield* TokenService.generate(user.id); + const session = yield* SessionService.create(user.id, token); + + return { user, token, session }; + }), +}; // Infrastructure Layer - External integrations const UserRepository = { findByEmail: (email: string) => Effect.tryPromise({ try: () => db.user.findUnique({ where: { email } }), - catch: (error) => new DatabaseError('Failed to find user', { cause: error }) - }) -} + catch: (error) => + new DatabaseError("Failed to find user", { cause: error }), + }), +}; // HTTP Layer - API endpoints -app.post('/auth/login', (req, res) => { +app.post("/auth/login", (req, res) => { Effect.runPromise( AuthService.login(req.body).pipe( - Effect.map(result => res.json(result)), - Effect.catchAll(error => Effect.sync(() => - res.status(400).json({ error: error.message }) - )) - ) - ) -}) + Effect.map((result) => res.json(result)), + Effect.catchAll((error) => + Effect.sync(() => res.status(400).json({ error: error.message })), + ), + ), + ); +}); ``` ## Design Principles @@ -101,6 +104,7 @@ app.post('/auth/login', (req, res) => { ### 1. Effect-First Architecture All business logic is built using Effect, providing: + - Composable error handling - Type-safe async operations - Built-in retry and timeout mechanisms @@ -122,17 +126,17 @@ Using Effect's context system for clean dependency management: class DatabaseService extends Context.Tag("DatabaseService")< DatabaseService, { - readonly query: (sql: string) => Effect.Effect + readonly query: (sql: string) => Effect.Effect; } >() {} // Use in business logic const getUser = (id: string) => Effect.gen(function* () { - const db = yield* DatabaseService - const result = yield* db.query(`SELECT * FROM users WHERE id = ?`, [id]) - return result[0] - }) + const db = yield* DatabaseService; + const result = yield* db.query(`SELECT * FROM users WHERE id = ?`, [id]); + return result[0]; + }); ``` ## Common Patterns @@ -142,25 +146,25 @@ const getUser = (id: string) => ```typescript // Define domain-specific errors class UserNotFoundError extends Data.TaggedError("UserNotFoundError")<{ - readonly userId: string + readonly userId: string; }> {} class ValidationError extends Data.TaggedError("ValidationError")<{ - readonly errors: Record + readonly errors: Record; }> {} // Use in services const updateUser = (id: string, data: UserUpdateData) => Effect.gen(function* () { - const validation = yield* validateUserData(data) - const user = yield* UserRepository.findById(id) - + const validation = yield* validateUserData(data); + const user = yield* UserRepository.findById(id); + if (!user) { - yield* Effect.fail(new UserNotFoundError({ userId: id })) + yield* Effect.fail(new UserNotFoundError({ userId: id })); } - - return yield* UserRepository.update(id, validation) - }) + + return yield* UserRepository.update(id, validation); + }); ``` ### Configuration Management @@ -170,15 +174,15 @@ const updateUser = (id: string, data: UserUpdateData) => class AppConfig extends Context.Tag("AppConfig")< AppConfig, { - readonly port: number + readonly port: number; readonly database: { - readonly url: string - readonly maxConnections: number - } + readonly url: string; + readonly maxConnections: number; + }; readonly auth: { - readonly jwtSecret: string - readonly sessionTimeout: number - } + readonly jwtSecret: string; + readonly sessionTimeout: number; + }; } >() {} @@ -186,19 +190,19 @@ class AppConfig extends Context.Tag("AppConfig")< const loadConfig = Effect.gen(function* () { const port = yield* Effect.fromNullable(process.env.PORT).pipe( Effect.map(Number), - Effect.orElse(() => Effect.succeed(3000)) - ) - + Effect.orElse(() => Effect.succeed(3000)), + ); + const databaseUrl = yield* Effect.fromNullable(process.env.DATABASE_URL).pipe( - Effect.orElseFail(() => new ConfigError('DATABASE_URL is required')) - ) - + Effect.orElseFail(() => new ConfigError("DATABASE_URL is required")), + ); + return { port, database: { url: databaseUrl, maxConnections: 10 }, - auth: { jwtSecret: process.env.JWT_SECRET!, sessionTimeout: 3600 } - } -}) + auth: { jwtSecret: process.env.JWT_SECRET!, sessionTimeout: 3600 }, + }; +}); ``` ### HTTP Middleware @@ -208,26 +212,28 @@ const loadConfig = Effect.gen(function* () { const authMiddleware = (req: Request) => Effect.gen(function* () { const token = yield* Effect.fromNullable(req.headers.authorization).pipe( - Effect.orElseFail(() => new UnauthorizedError('Missing authorization header')) - ) - - const user = yield* TokenService.verify(token.replace('Bearer ', '')) - - return { ...req, user } - }) + Effect.orElseFail( + () => new UnauthorizedError("Missing authorization header"), + ), + ); + + const user = yield* TokenService.verify(token.replace("Bearer ", "")); + + return { ...req, user }; + }); // Use in routes -app.get('/protected', (req, res) => { +app.get("/protected", (req, res) => { Effect.runPromise( authMiddleware(req).pipe( - Effect.flatMap(authedReq => getProtectedData(authedReq.user.id)), - Effect.map(data => res.json(data)), - Effect.catchAll(error => Effect.sync(() => - res.status(401).json({ error: error.message }) - )) - ) - ) -}) + Effect.flatMap((authedReq) => getProtectedData(authedReq.user.id)), + Effect.map((data) => res.json(data)), + Effect.catchAll((error) => + Effect.sync(() => res.status(401).json({ error: error.message })), + ), + ), + ); +}); ``` ## Integration Examples @@ -235,59 +241,61 @@ app.get('/protected', (req, res) => { ### Express.js Integration ```typescript -import express from 'express' -import { Effect, Layer } from 'effect' +import express from "express"; +import { Effect, Layer } from "effect"; -const app = express() +const app = express(); // Effect-based route handler const createUser = (userData: CreateUserData) => Effect.gen(function* () { - const validation = yield* validateUserData(userData) - const hashedPassword = yield* PasswordService.hash(validation.password) + const validation = yield* validateUserData(userData); + const hashedPassword = yield* PasswordService.hash(validation.password); const user = yield* UserRepository.create({ ...validation, - password: hashedPassword - }) - - return user - }) + password: hashedPassword, + }); + + return user; + }); -app.post('/users', (req, res) => { +app.post("/users", (req, res) => { Effect.runPromise( createUser(req.body).pipe( - Effect.map(user => res.status(201).json(user)), - Effect.catchTag('ValidationError', error => - Effect.sync(() => res.status(400).json({ errors: error.errors })) + Effect.map((user) => res.status(201).json(user)), + Effect.catchTag("ValidationError", (error) => + Effect.sync(() => res.status(400).json({ errors: error.errors })), + ), + Effect.catchAll((error) => + Effect.sync(() => + res.status(500).json({ error: "Internal server error" }), + ), ), - Effect.catchAll(error => - Effect.sync(() => res.status(500).json({ error: 'Internal server error' })) - ) - ) - ) -}) + ), + ); +}); ``` ### Database Integration ```typescript -import { Pool } from 'pg' +import { Pool } from "pg"; // Create database service const makeDatabaseService = Effect.gen(function* () { - const config = yield* AppConfig - const pool = new Pool({ connectionString: config.database.url }) - + const config = yield* AppConfig; + const pool = new Pool({ connectionString: config.database.url }); + return { query: (sql: string, params: any[] = []) => Effect.tryPromise({ - try: () => pool.query(sql, params).then(result => result.rows), - catch: (error) => new DatabaseError('Query failed', { cause: error }) - }) - } -}) + try: () => pool.query(sql, params).then((result) => result.rows), + catch: (error) => new DatabaseError("Query failed", { cause: error }), + }), + }; +}); -const DatabaseServiceLive = Layer.effect(DatabaseService, makeDatabaseService) +const DatabaseServiceLive = Layer.effect(DatabaseService, makeDatabaseService); ``` ## Testing @@ -295,33 +303,30 @@ const DatabaseServiceLive = Layer.effect(DatabaseService, makeDatabaseService) Effect provides excellent testing utilities for backend applications: ```typescript -import { Effect, Layer, TestContext } from 'effect' +import { Effect, Layer, TestContext } from "effect"; // Mock services for testing const MockUserRepository = Layer.succeed(UserRepository, { - findById: (id: string) => - id === 'existing-user' - ? Effect.succeed({ id, email: 'test@example.com' }) + findById: (id: string) => + id === "existing-user" + ? Effect.succeed({ id, email: "test@example.com" }) : Effect.fail(new UserNotFoundError({ userId: id })), - - create: (data: CreateUserData) => - Effect.succeed({ id: 'new-user', ...data }) -}) + + create: (data: CreateUserData) => Effect.succeed({ id: "new-user", ...data }), +}); // Test with mocked dependencies const testCreateUser = Effect.gen(function* () { const result = yield* createUser({ - email: 'test@example.com', - password: 'password123' - }) - - expect(result.email).toBe('test@example.com') -}).pipe( - Effect.provide(MockUserRepository) -) + email: "test@example.com", + password: "password123", + }); + + expect(result.email).toBe("test@example.com"); +}).pipe(Effect.provide(MockUserRepository)); // Run test -Effect.runPromise(testCreateUser) +Effect.runPromise(testCreateUser); ``` ## Deployment @@ -351,13 +356,13 @@ const ProductionConfig = Layer.succeed(AppConfig, { port: Number(process.env.PORT) || 3000, database: { url: process.env.DATABASE_URL!, - maxConnections: Number(process.env.DB_MAX_CONNECTIONS) || 20 + maxConnections: Number(process.env.DB_MAX_CONNECTIONS) || 20, }, auth: { jwtSecret: process.env.JWT_SECRET!, - sessionTimeout: Number(process.env.SESSION_TIMEOUT) || 3600 - } -}) + sessionTimeout: Number(process.env.SESSION_TIMEOUT) || 3600, + }, +}); ``` ## Community & Support diff --git a/apps/docs/src/content/docs/backend/installation.md b/apps/docs/src/content/docs/backend/installation.md index 833ba284..3d8aa63b 100644 --- a/apps/docs/src/content/docs/backend/installation.md +++ b/apps/docs/src/content/docs/backend/installation.md @@ -573,10 +573,10 @@ testRoutes.get("/db-test", (req, res) => { ## Next Steps -- [Getting Started Guide](backend/getting-started/) - Learn the basics -- [Node Better Auth](backend/packages/node-better-auth/) - Explore authentication -- [Node Auth App](backend/packages/node-auth-app/) - Complete auth service -- [Backend Reference](backend/reference/) - API documentation +- [Getting Started Guide](getting-started/) - Learn the basics +- [Node Better Auth](packages/node-better-auth/) - Explore authentication +- [Node Auth App](packages/node-auth-app/) - Complete auth service +- [Backend Reference](reference/) - API documentation ## Troubleshooting diff --git a/apps/docs/src/content/docs/react/getting-started.md b/apps/docs/src/content/docs/react/getting-started.md index 3bcab9c6..09d9bc2e 100644 --- a/apps/docs/src/content/docs/react/getting-started.md +++ b/apps/docs/src/content/docs/react/getting-started.md @@ -102,7 +102,11 @@ interface UserProfileProps { } export function UserProfile({ userId }: UserProfileProps) { - const { data: user, isLoading, error } = useQuery({ + const { + data: user, + isLoading, + error, + } = useQuery({ queryKey: ["user", userId], queryFn: () => Effect.runPromise(fetchUser(userId)), }) @@ -124,9 +128,9 @@ export function UserProfile({ userId }: UserProfileProps) { Now that you have the basics set up, explore the specific packages: -- [React Query Integration](react/packages/react-query/) - Learn advanced patterns for data fetching -- [UI Components](react/packages/react-ui/) - Explore the component library -- [Chat Components](react/packages/chat-react/) - Add real-time features +- [React Query Integration](packages/react-query/) - Learn advanced patterns for data fetching +- [UI Components](packages/react-ui/) - Explore the component library +- [Chat Components](packages/chat-react/) - Add real-time features ## Common Patterns @@ -148,10 +152,7 @@ You can compose multiple Effects together: ```tsx const fetchUserWithPosts = (id: number) => - Effect.all([ - fetchUser(id), - fetchUserPosts(id), - ]).pipe( + Effect.all([fetchUser(id), fetchUserPosts(id)]).pipe( Effect.map(([user, posts]) => ({ user, posts })), ) ``` diff --git a/apps/docs/src/content/docs/react/index.mdx b/apps/docs/src/content/docs/react/index.mdx index 9f73a993..1486e932 100644 --- a/apps/docs/src/content/docs/react/index.mdx +++ b/apps/docs/src/content/docs/react/index.mdx @@ -15,19 +15,19 @@ Effectify provides powerful React integrations that combine the type-safety and Effect integration with TanStack Query for React applications. Provides type-safe data fetching with Effect's error handling. - [Learn more →](react/packages/react-query/) + [Learn more →](packages/react-query/) A comprehensive UI component library built with React, Radix UI, and Tailwind CSS. Includes forms, layouts, and interactive components. - [Learn more →](react/packages/react-ui/) + [Learn more →](packages/react-ui/) Real-time chat components and services for React applications. Built with Effect for robust state management and error handling. - [Learn more →](react/packages/chat-react/) + [Learn more →](packages/chat-react/) @@ -38,7 +38,7 @@ Ready to start building with Effectify and React? Check out our getting started Get up and running with Effectify in your React application in minutes. - [Get Started →](react/getting-started/) + [Get Started →](getting-started/) ## Key Features diff --git a/apps/docs/src/content/docs/react/installation.md b/apps/docs/src/content/docs/react/installation.md index 0573cd5c..34432923 100644 --- a/apps/docs/src/content/docs/react/installation.md +++ b/apps/docs/src/content/docs/react/installation.md @@ -125,11 +125,7 @@ import { useState } from "react" export function Providers({ children }: { children: React.ReactNode }) { const [queryClient] = useState(() => new QueryClient()) - return ( - - {children} - - ) + return {children} } ``` @@ -210,9 +206,7 @@ Ensure your `tsconfig.json` includes proper configuration: "noEmit": true, "jsx": "react-jsx" }, - "include": [ - "src" - ] + "include": ["src"] } ``` @@ -241,6 +235,6 @@ If you see "Effectify is working!" rendered, your installation is successful! ## Next Steps -- [Getting Started Guide](react/getting-started/) - Learn the basics -- [React Query Package](react/packages/react-query/) - Explore data fetching patterns -- [UI Components](react/packages/react-ui/) - Browse available components +- [Getting Started Guide](getting-started/) - Learn the basics +- [React Query Package](packages/react-query/) - Explore data fetching patterns +- [UI Components](packages/react-ui/) - Browse available components diff --git a/apps/docs/src/content/docs/solid/getting-started.md b/apps/docs/src/content/docs/solid/getting-started.md index bcabf48c..302450c0 100644 --- a/apps/docs/src/content/docs/solid/getting-started.md +++ b/apps/docs/src/content/docs/solid/getting-started.md @@ -289,9 +289,9 @@ function UserDashboard(props: { userId: number }) { Now that you have the basics set up, explore the specific packages: -- [Solid Query Integration](solid/packages/solid-query/) - Learn advanced patterns for data fetching -- [UI Components](solid/packages/solid-ui/) - Explore the component library -- [Chat Components](solid/packages/chat-solid/) - Add real-time features +- [Solid Query Integration](packages/solid-query/) - Learn advanced patterns for data fetching +- [UI Components](packages/solid-ui/) - Explore the component library +- [Chat Components](packages/chat-solid/) - Add real-time features ## Common Patterns diff --git a/apps/docs/src/content/docs/solid/index.mdx b/apps/docs/src/content/docs/solid/index.mdx index 25256754..2e0258e6 100644 --- a/apps/docs/src/content/docs/solid/index.mdx +++ b/apps/docs/src/content/docs/solid/index.mdx @@ -15,19 +15,19 @@ Effectify provides powerful SolidJS integrations that combine the reactive natur Effect integration with TanStack Query for SolidJS applications. Provides type-safe data fetching with Effect's error handling and SolidJS reactivity. - [Learn more →](solid/packages/solid-query/) + [Learn more →](packages/solid-query/) A comprehensive UI component library built with SolidJS, Kobalte, and Tailwind CSS. Includes forms, layouts, and interactive components optimized for SolidJS. - [Learn more →](solid/packages/solid-ui/) + [Learn more →](packages/solid-ui/) Real-time chat components and services for SolidJS applications. Built with Effect for robust state management and SolidJS for reactive UI updates. - [Learn more →](solid/packages/chat-solid/) + [Learn more →](packages/chat-solid/) @@ -38,7 +38,7 @@ Ready to start building with Effectify and SolidJS? Check out our getting starte Get up and running with Effectify in your SolidJS application in minutes. - [Get Started →](solid/getting-started/) + [Get Started →](getting-started/) ## Key Features diff --git a/apps/docs/src/content/docs/solid/installation.md b/apps/docs/src/content/docs/solid/installation.md index 1bbb02ff..1f5755cc 100644 --- a/apps/docs/src/content/docs/solid/installation.md +++ b/apps/docs/src/content/docs/solid/installation.md @@ -383,10 +383,10 @@ function App() { ## Next Steps -- [Getting Started Guide](solid/getting-started/) - Learn the basics -- [Solid Query Package](solid/packages/solid-query/) - Explore data fetching patterns -- [UI Components](solid/packages/solid-ui/) - Browse available components -- [Chat Components](solid/packages/chat-solid/) - Add real-time features +- [Getting Started Guide](getting-started/) - Learn the basics +- [Solid Query Package](packages/solid-query/) - Explore data fetching patterns +- [UI Components](packages/solid-ui/) - Browse available components +- [Chat Components](packages/chat-solid/) - Add real-time features ## Troubleshooting diff --git a/apps/docs/src/content/docs/universal/getting-started.md b/apps/docs/src/content/docs/universal/getting-started.md index 63c058ba..5da9c2a0 100644 --- a/apps/docs/src/content/docs/universal/getting-started.md +++ b/apps/docs/src/content/docs/universal/getting-started.md @@ -527,9 +527,9 @@ app.post("/users", (req, res) => { Now that you understand the core concepts, explore the specific universal packages: -- [Chat Domain](universal/packages/chat-domain/) - Learn chat domain logic -- [Shared Types](universal/packages/shared-types/) - Explore common types -- [Universal Concepts](universal/concepts/) - Dive deeper into patterns +- [Chat Domain](packages/chat-domain/) - Learn chat domain logic +- [Shared Types](packages/shared-types/) - Explore common types +- [Universal Concepts](concepts/) - Dive deeper into patterns ## Best Practices diff --git a/apps/docs/src/content/docs/universal/index.mdx b/apps/docs/src/content/docs/universal/index.mdx index 4c43754f..c54895e6 100644 --- a/apps/docs/src/content/docs/universal/index.mdx +++ b/apps/docs/src/content/docs/universal/index.mdx @@ -15,13 +15,13 @@ Effectify's universal packages provide shared functionality, types, and domain l Domain logic and business rules for chat functionality. Provides pure, framework-agnostic chat operations built with Effect. - [Learn more →](universal/packages/chat-domain/) + [Learn more →](packages/chat-domain/) Common TypeScript types and interfaces shared across all Effectify packages. Ensures type consistency throughout your application. - [Learn more →](universal/packages/shared-types/) + [Learn more →](packages/shared-types/) @@ -32,7 +32,7 @@ Ready to understand the universal concepts that power Effectify? Check out our g Learn the core concepts and patterns used across all Effectify packages. - [Get Started →](universal/getting-started/) + [Get Started →](getting-started/) ## Core Principles