UNPKG

@xtr-dev/zod-rpc

Version:

Simple, type-safe RPC library with Zod validation and automatic TypeScript inference

176 lines 5.49 kB
import { z, ZodSchema } from 'zod'; /** * Core message structure for RPC communication between clients and servers. * Every RPC call, response, and error is transmitted as an RPCMessage. * * @example * ```typescript * const requestMessage: RPCMessage = { * callerId: 'client-123', * targetId: 'server', * traceId: 'trace-456', * methodId: 'user.get', * payload: { userId: '789' }, * type: 'request' * }; * ``` * * @group Core Types */ export interface RPCMessage { /** Unique identifier of the client or server sending this message */ callerId: string; /** Unique identifier of the intended recipient for this message */ targetId: string; /** Unique identifier for tracking this request-response cycle */ traceId: string; /** Full method identifier in the format 'serviceName.methodName' */ methodId: string; /** The actual data being sent - request parameters, response data, or error details */ payload: unknown; /** Type of message - determines how the payload should be interpreted */ type: 'request' | 'response' | 'error'; } /** * Internal definition of an RPC method with its validation schemas and implementation. * This is created when implementing services on the server side. * * @template T - Zod schema type for input validation * @template U - Zod schema type for output validation * * @example * ```typescript * const getUserMethod: MethodDefinition<typeof inputSchema, typeof outputSchema> = { * id: 'user.get', * targetId: 'server', * input: z.object({ userId: z.string() }), * output: z.object({ name: z.string(), email: z.string() }), * handler: async ({ userId }) => ({ name: 'John', email: 'john@example.com' }) * }; * ``` * * @group Core Types */ export interface MethodDefinition<T extends ZodSchema, U extends ZodSchema> { /** Full method identifier in format 'serviceName.methodName' */ id: string; /** Target server/service that should handle this method */ targetId: string; /** Zod schema for validating input parameters */ input: T; /** Zod schema for validating output/return values */ output: U; /** The actual implementation function that processes the request */ handler: (input: z.infer<T>) => Promise<z.infer<U>>; } /** * Metadata about an RPC method for introspection and documentation purposes. * * @example * ```typescript * const methodInfo: MethodInfo = { * id: 'user.get', * name: 'get' * }; * ``` * * @group Core Types */ export interface MethodInfo { /** Full method identifier in format 'serviceName.methodName' */ id: string; /** Short method name without service prefix */ name: string; } /** * Metadata about an RPC service and its available methods. * Used for service discovery and API documentation generation. * * @example * ```typescript * const serviceInfo: ServiceInfo = { * id: 'user', * methods: [ * { id: 'user.get', name: 'get' }, * { id: 'user.create', name: 'create' } * ] * }; * ``` * * @group Core Types */ export interface ServiceInfo { /** Unique service identifier */ id: string; /** List of all methods available in this service */ methods: MethodInfo[]; } /** * Type utility to extract the input type from a MethodDefinition. * Automatically infers TypeScript types from Zod input schemas. * * @template T - MethodDefinition type to extract input from * * @example * ```typescript * const method: MethodDefinition<typeof inputSchema, typeof outputSchema> = {...}; * type InputType = InferInput<typeof method>; // { userId: string } * ``` * * @group Core Types */ export type InferInput<T> = T extends MethodDefinition<infer I, any> ? z.infer<I> : never; /** * Type utility to extract the output type from a MethodDefinition. * Automatically infers TypeScript types from Zod output schemas. * * @template T - MethodDefinition type to extract output from * * @example * ```typescript * const method: MethodDefinition<typeof inputSchema, typeof outputSchema> = {...}; * type OutputType = InferOutput<typeof method>; // { name: string; email: string } * ``` * * @group Core Types */ export type InferOutput<T> = T extends MethodDefinition<any, infer O> ? z.infer<O> : never; /** * Abstract interface for transport layers that handle RPC message delivery. * Different transports (WebSocket, HTTP, WebRTC) implement this interface * to provide a consistent API for the RPC layer. * * @example * ```typescript * const transport: Transport = createWebSocketTransport('ws://localhost:8080'); * * await transport.connect(); * transport.onMessage((message) => { * console.log('Received:', message); * }); * * await transport.send({ * callerId: 'client', * targetId: 'server', * traceId: 'trace-123', * methodId: 'user.get', * payload: { userId: '123' }, * type: 'request' * }); * ``` * * @group Transport Layer */ export interface Transport { /** Send an RPC message through this transport */ send(message: RPCMessage): Promise<void>; /** Register a handler for incoming messages */ onMessage(handler: (message: RPCMessage) => void): void; /** Establish connection to the remote endpoint */ connect(): Promise<void>; /** Close connection and cleanup resources */ disconnect(): Promise<void>; /** Check if transport is currently connected */ isConnected(): boolean; } //# sourceMappingURL=types.d.ts.map