Skip to content

Latest commit

 

History

History
235 lines (169 loc) · 6.64 KB

File metadata and controls

235 lines (169 loc) · 6.64 KB

socketrpc-gen Examples

This directory contains examples demonstrating different use cases and features of socketrpc-gen.

Quick Start

Each example is self-contained with its own README. To try an example:

cd examples/01-basic
bun run ../../index.ts ./define.ts

Examples Overview

00-full-app - Complete Working Application

What it demonstrates:

  • Complete client/server implementation (not just interfaces)
  • Actual usage of generated RPC code in a real application
  • Project structure with webapp, client, and server packages
  • Practical patterns for production use

Complexity: ⭐⭐ Intermediate

Use when:

  • You want to see a complete working example
  • You're starting a new project and need a template
  • You want to understand how all pieces fit together

Note: This is the most comprehensive example with actual implementation code.


01-basic - Basic RPC Interfaces

What it demonstrates:

  • Simple interface definitions without any extension
  • Basic client-server RPC communication
  • Fire-and-forget functions (void return)
  • Functions with return values

Complexity: ⭐ Beginner

Use when:

  • Starting a new project
  • You don't need interface inheritance
  • Simple client-server communication

Functions generated: 5 total (3 server, 2 client)


02-single-extension - Single-Level Extension

What it demonstrates:

  • Extending base interfaces with application-specific functions
  • Separating framework and application logic
  • Type reuse across interface inheritance

Complexity: ⭐⭐ Intermediate

Use when:

  • Building a framework that others will extend
  • Separating common functionality from app-specific features
  • Creating reusable interface libraries

Functions generated: 11 total (6 server, 5 client)

Structure:

base.define.ts → define.ts
(framework)      (application)

03-multi-level-extension - Multi-Level Extension

What it demonstrates:

  • Multiple levels of interface inheritance
  • Layered architecture (Framework → Platform → Application)
  • Complex type resolution across multiple files
  • Enterprise-scale architecture patterns

Complexity: ⭐⭐⭐ Advanced

Use when:

  • Building large-scale applications with multiple layers
  • Creating plugin systems
  • Developing microservices with shared base functionality
  • Framework → Platform → Application architecture

Functions generated: 15 total (8 server, 7 client)

Structure:

framework.define.ts → platform.define.ts → define.ts
(core)                (auth/users)         (business logic)

04-zod-integration - Zod Schema Compatibility

What it demonstrates:

  • Using Zod schemas with socket-rpc
  • Inferring TypeScript types from Zod using z.infer<>
  • Compatibility with AI frameworks (Claude Agent SDK, etc.)
  • Single source of truth: Zod schemas define structure, types are derived

Complexity: ⭐⭐ Intermediate

Use when:

  • Integrating with AI frameworks that use Zod for structured outputs
  • You already have Zod schemas and want to reuse them
  • You prefer schema-first development

Functions generated: 8 total (5 server, 3 client)

Key pattern:

// Define schema once
export const TaskSchema = z.object({
  id: z.string().uuid(),
  title: z.string(),
  status: z.enum(['pending', 'completed'])
});

// Infer type from schema
export type Task = z.infer<typeof TaskSchema>;

// Use in interface
interface ServerFunctions {
  getTask: (id: string) => Task;
}

Feature Comparison

Feature Example 00 Example 01 Example 02 Example 03 Example 04
Full Implementation
Interface Extension ✅ Multi-level ✅ Single-level ✅ Multi-level
Zod Schemas
Multiple Files ✅ 3 files ✅ 2 files ✅ 3 files
Layered Architecture ✅ 3 layers ✅ 2 layers ✅ 3 layers
Client/Server Code
Complexity Medium Low Medium High Medium
Real-world Use Production app Simple apps Frameworks Enterprise AI Integration

Common Patterns

Pattern 1: Framework Base Classes (Example 02)

Create a base.define.ts with common functions:

  • Error handling (showError)
  • Success notifications (showSuccess)
  • Health checks (ping)
  • Utility functions

Then extend in your define.ts with business logic.

Pattern 2: Layered Architecture (Example 03)

Structure your interfaces in layers:

  1. Framework Layer: Core functionality (logging, health)
  2. Platform Layer: Cross-cutting concerns (auth, monitoring)
  3. Application Layer: Business logic (orders, products)

Each layer extends the one below it.

Pattern 3: Plugin System

Base application provides core interfaces, plugins extend with additional functions:

// core.define.ts
export interface CoreFunctions { ... }

// plugin-a.define.ts
export interface PluginAFunctions extends CoreFunctions { ... }

// plugin-b.define.ts
export interface PluginBFunctions extends CoreFunctions { ... }

Testing Examples

To verify all examples work:

# Test example 01
cd examples/01-basic
bun run ../../index.ts ./define.ts

# Test example 02
cd ../02-single-extension
bun run ../../index.ts ./define.ts

# Test example 03
cd ../03-multi-level-extension
bun run ../../index.ts ./define.ts

# Test example 04 (requires zod)
cd ../04-zod-integration
bun add zod  # if not already installed
bun run ../../index.ts ./define.ts
bun run test.ts  # verify types work

Each should generate without errors and produce client.generated.ts, server.generated.ts, and types.generated.ts.

Tips

  1. Start Simple: Begin with Example 01, then move to extensions as your needs grow
  2. File Organization: Keep definition files close to where they're used
  3. Naming Convention: Use *.define.ts for interface definition files
  4. Documentation: Document your interfaces well - JSDoc comments are preserved
  5. Type Safety: Export all custom types from your definition files

Next Steps

After trying these examples:

  1. Check the generated code to understand what's created
  2. Read the main documentation for CLI options
  3. Integrate into your project
  4. Consider which pattern fits your architecture

Questions?