@parsrun/service 0.1.28 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +30 -3
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/define.d.ts +29 -6
- package/dist/define.js.map +1 -1
- package/dist/events/index.d.ts +95 -15
- package/dist/events/index.js.map +1 -1
- package/dist/{handler-CmiDUWZv.d.ts → handler-eCIZLODd.d.ts} +45 -3
- package/dist/{index-CVOAoJjZ.d.ts → index-reEpIe1R.d.ts} +82 -11
- package/dist/index.d.ts +53 -9
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/resilience/index.d.ts +76 -9
- package/dist/resilience/index.js +1 -0
- package/dist/resilience/index.js.map +1 -1
- package/dist/rpc/index.d.ts +3 -3
- package/dist/rpc/index.js +1 -0
- package/dist/rpc/index.js.map +1 -1
- package/dist/serialization/index.d.ts +27 -2
- package/dist/serialization/index.js.map +1 -1
- package/dist/{server-DFE8n2Sx.d.ts → server-BB9AbnkP.d.ts} +50 -6
- package/dist/tracing/index.d.ts +94 -15
- package/dist/tracing/index.js.map +1 -1
- package/dist/transports/cloudflare/index.d.ts +72 -10
- package/dist/transports/cloudflare/index.js.map +1 -1
- package/dist/{types-n4LLSPQU.d.ts → types-DHZaZwAt.d.ts} +51 -0
- package/package.json +3 -3
package/dist/rpc/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/rpc/client.ts","../../src/config.ts","../../src/rpc/errors.ts","../../src/resilience/circuit-breaker.ts","../../src/resilience/bulkhead.ts","../../src/resilience/retry.ts","../../src/resilience/timeout.ts","../../src/rpc/server.ts","../../src/define.ts","../../src/rpc/transports/embedded.ts","../../src/serialization/index.ts","../../src/rpc/transports/http.ts"],"sourcesContent":["/**\n * @parsrun/service - RPC Client\n * Client for making RPC calls to services\n */\n\nimport { generateId } from \"@parsrun/core\";\nimport type {\n RpcRequest,\n RpcTransport,\n RpcMetadata,\n TraceContext,\n ServiceConfig,\n} from \"../types.js\";\nimport { mergeConfig } from \"../config.js\";\nimport { TimeoutError, toRpcError } from \"./errors.js\";\nimport {\n CircuitBreaker,\n Bulkhead,\n withRetry,\n withTimeout,\n} from \"../resilience/index.js\";\n\n// ============================================================================\n// RPC CLIENT\n// ============================================================================\n\nexport interface RpcClientOptions {\n /** Service name */\n service: string;\n /** RPC transport */\n transport: RpcTransport;\n /** Service configuration */\n config?: ServiceConfig;\n /** Default metadata for all requests */\n defaultMetadata?: RpcMetadata;\n}\n\n/**\n * RPC Client for making service calls\n */\nexport class RpcClient {\n private readonly service: string;\n private readonly transport: RpcTransport;\n private readonly config: Required<ServiceConfig>;\n private readonly defaultMetadata: RpcMetadata;\n private readonly circuitBreaker: CircuitBreaker | null;\n private readonly bulkhead: Bulkhead | null;\n\n constructor(options: RpcClientOptions) {\n this.service = options.service;\n this.transport = options.transport;\n this.config = mergeConfig(options.config);\n this.defaultMetadata = options.defaultMetadata ?? {};\n\n // Initialize circuit breaker\n const cbConfig = this.config.resilience?.circuitBreaker;\n if (\n cbConfig &&\n cbConfig.enabled &&\n cbConfig.failureThreshold !== undefined &&\n cbConfig.resetTimeout !== undefined &&\n cbConfig.successThreshold !== undefined\n ) {\n this.circuitBreaker = new CircuitBreaker({\n failureThreshold: cbConfig.failureThreshold,\n resetTimeout: cbConfig.resetTimeout,\n successThreshold: cbConfig.successThreshold,\n });\n } else {\n this.circuitBreaker = null;\n }\n\n // Initialize bulkhead\n const bhConfig = this.config.resilience?.bulkhead;\n if (bhConfig && bhConfig.maxConcurrent !== undefined && bhConfig.maxQueue !== undefined) {\n this.bulkhead = new Bulkhead({\n maxConcurrent: bhConfig.maxConcurrent,\n maxQueue: bhConfig.maxQueue,\n });\n } else {\n this.bulkhead = null;\n }\n }\n\n /**\n * Execute a query\n */\n async query<TInput, TOutput>(\n method: string,\n input: TInput,\n options?: CallOptions\n ): Promise<TOutput> {\n return this.call<TInput, TOutput>(\"query\", method, input, options);\n }\n\n /**\n * Execute a mutation\n */\n async mutate<TInput, TOutput>(\n method: string,\n input: TInput,\n options?: CallOptions\n ): Promise<TOutput> {\n return this.call<TInput, TOutput>(\"mutation\", method, input, options);\n }\n\n /**\n * Internal call implementation\n */\n private async call<TInput, TOutput>(\n type: \"query\" | \"mutation\",\n method: string,\n input: TInput,\n options?: CallOptions\n ): Promise<TOutput> {\n const request: RpcRequest<TInput> = {\n id: generateId(),\n service: this.service,\n method,\n type,\n input,\n metadata: {\n ...this.defaultMetadata,\n ...options?.metadata,\n },\n };\n\n const version = options?.version ?? this.config.versioning.defaultVersion;\n if (version) {\n request.version = version;\n }\n if (options?.traceContext) {\n request.traceContext = options.traceContext;\n }\n\n const timeout = options?.timeout ?? this.config.resilience.timeout ?? 30_000;\n const retryConfig = options?.retry ?? this.config.resilience.retry;\n\n // Build the execution chain\n let execute = async (): Promise<TOutput> => {\n const response = await this.transport.call<TInput, TOutput>(request);\n\n if (!response.success) {\n const error = toRpcError(\n new Error(response.error?.message ?? \"Unknown error\")\n );\n throw error;\n }\n\n return response.output as TOutput;\n };\n\n // Wrap with timeout\n execute = withTimeout(execute, timeout, () => {\n throw new TimeoutError(this.service, method, timeout);\n });\n\n // Wrap with retry\n const attempts = retryConfig?.attempts ?? 0;\n if (attempts > 0) {\n execute = withRetry(execute, {\n attempts,\n backoff: retryConfig?.backoff ?? \"exponential\",\n initialDelay: retryConfig?.initialDelay ?? 100,\n maxDelay: retryConfig?.maxDelay ?? 5000,\n shouldRetry: (error) => {\n if (error instanceof Error && \"retryable\" in error) {\n return (error as { retryable: boolean }).retryable;\n }\n return false;\n },\n });\n }\n\n // Wrap with circuit breaker\n if (this.circuitBreaker) {\n const cb = this.circuitBreaker;\n const originalExecute = execute;\n execute = async () => {\n return cb.execute(originalExecute);\n };\n }\n\n // Wrap with bulkhead\n if (this.bulkhead) {\n const bh = this.bulkhead;\n const originalExecute = execute;\n execute = async () => {\n return bh.execute(originalExecute);\n };\n }\n\n return execute();\n }\n\n /**\n * Get circuit breaker state\n */\n getCircuitState(): \"closed\" | \"open\" | \"half-open\" | null {\n return this.circuitBreaker?.state ?? null;\n }\n\n /**\n * Get bulkhead stats\n */\n getBulkheadStats(): { concurrent: number; queued: number } | null {\n if (!this.bulkhead) return null;\n return {\n concurrent: this.bulkhead.concurrent,\n queued: this.bulkhead.queued,\n };\n }\n\n /**\n * Close the client and release resources\n */\n async close(): Promise<void> {\n await this.transport.close?.();\n }\n}\n\n/**\n * Call options\n */\nexport interface CallOptions {\n /** Timeout in ms */\n timeout?: number;\n /** Version requirement */\n version?: string;\n /** Trace context */\n traceContext?: TraceContext;\n /** Request metadata */\n metadata?: RpcMetadata;\n /** Retry configuration override */\n retry?: {\n attempts?: number;\n backoff?: \"linear\" | \"exponential\";\n initialDelay?: number;\n maxDelay?: number;\n };\n}\n\n/**\n * Create an RPC client\n */\nexport function createRpcClient(options: RpcClientOptions): RpcClient {\n return new RpcClient(options);\n}\n","/**\n * @parsrun/service - Configuration\n * Default configuration and config utilities\n */\n\nimport type {\n ServiceConfig,\n EventFormatConfig,\n SerializationConfig,\n TracingConfig,\n VersioningConfig,\n ResilienceConfig,\n DeadLetterConfig,\n} from \"./types.js\";\n\n// ============================================================================\n// DEFAULT CONFIGURATIONS\n// ============================================================================\n\nexport const DEFAULT_EVENT_CONFIG: Required<EventFormatConfig> = {\n format: \"cloudevents\",\n internalCompact: true,\n};\n\nexport const DEFAULT_SERIALIZATION_CONFIG: Required<SerializationConfig> = {\n format: \"json\",\n};\n\nexport const DEFAULT_TRACING_CONFIG: Required<TracingConfig> = {\n enabled: true,\n sampler: { ratio: 0.1 },\n exporter: \"console\",\n endpoint: \"\",\n serviceName: \"pars-service\",\n};\n\nexport const DEFAULT_VERSIONING_CONFIG: Required<VersioningConfig> = {\n strategy: \"header\",\n defaultVersion: \"1.x\",\n};\n\nexport const DEFAULT_RESILIENCE_CONFIG: Required<ResilienceConfig> = {\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n resetTimeout: 30_000,\n successThreshold: 2,\n },\n bulkhead: {\n maxConcurrent: 100,\n maxQueue: 50,\n },\n timeout: 5_000,\n retry: {\n attempts: 3,\n backoff: \"exponential\",\n initialDelay: 100,\n maxDelay: 10_000,\n },\n};\n\nexport const DEFAULT_DEAD_LETTER_CONFIG: Required<DeadLetterConfig> = {\n enabled: true,\n retention: \"30d\",\n onFail: \"alert\",\n alertThreshold: 10,\n};\n\nexport const DEFAULT_SERVICE_CONFIG: Required<ServiceConfig> = {\n events: DEFAULT_EVENT_CONFIG,\n serialization: DEFAULT_SERIALIZATION_CONFIG,\n tracing: DEFAULT_TRACING_CONFIG,\n versioning: DEFAULT_VERSIONING_CONFIG,\n resilience: DEFAULT_RESILIENCE_CONFIG,\n deadLetter: DEFAULT_DEAD_LETTER_CONFIG,\n};\n\n// ============================================================================\n// CONFIG UTILITIES\n// ============================================================================\n\n/**\n * Merge user config with defaults\n */\nexport function mergeConfig(userConfig?: Partial<ServiceConfig>): Required<ServiceConfig> {\n if (!userConfig) {\n return { ...DEFAULT_SERVICE_CONFIG };\n }\n\n return {\n events: {\n ...DEFAULT_EVENT_CONFIG,\n ...userConfig.events,\n },\n serialization: {\n ...DEFAULT_SERIALIZATION_CONFIG,\n ...userConfig.serialization,\n },\n tracing: {\n ...DEFAULT_TRACING_CONFIG,\n ...userConfig.tracing,\n },\n versioning: {\n ...DEFAULT_VERSIONING_CONFIG,\n ...userConfig.versioning,\n },\n resilience: {\n ...DEFAULT_RESILIENCE_CONFIG,\n ...userConfig.resilience,\n circuitBreaker: {\n ...DEFAULT_RESILIENCE_CONFIG.circuitBreaker,\n ...userConfig.resilience?.circuitBreaker,\n },\n bulkhead: {\n ...DEFAULT_RESILIENCE_CONFIG.bulkhead,\n ...userConfig.resilience?.bulkhead,\n },\n retry: {\n ...DEFAULT_RESILIENCE_CONFIG.retry,\n ...userConfig.resilience?.retry,\n },\n },\n deadLetter: {\n ...DEFAULT_DEAD_LETTER_CONFIG,\n ...userConfig.deadLetter,\n },\n };\n}\n\n/**\n * Create config for development\n */\nexport function createDevConfig(overrides?: Partial<ServiceConfig>): Required<ServiceConfig> {\n return mergeConfig({\n tracing: {\n enabled: true,\n sampler: \"always\",\n exporter: \"console\",\n },\n resilience: {\n circuitBreaker: { enabled: false },\n timeout: 30_000,\n },\n ...overrides,\n });\n}\n\n/**\n * Create config for production\n */\nexport function createProdConfig(overrides?: Partial<ServiceConfig>): Required<ServiceConfig> {\n return mergeConfig({\n tracing: {\n enabled: true,\n sampler: { ratio: 0.1 },\n exporter: \"otlp\",\n },\n resilience: {\n circuitBreaker: { enabled: true },\n timeout: 5_000,\n },\n ...overrides,\n });\n}\n\n/**\n * Validate config\n */\nexport function validateConfig(config: ServiceConfig): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Validate tracing\n if (config.tracing?.sampler && typeof config.tracing.sampler === \"object\") {\n const ratio = config.tracing.sampler.ratio;\n if (ratio < 0 || ratio > 1) {\n errors.push(\"tracing.sampler.ratio must be between 0 and 1\");\n }\n }\n\n // Validate resilience\n if (config.resilience?.timeout !== undefined && config.resilience.timeout < 0) {\n errors.push(\"resilience.timeout must be non-negative\");\n }\n\n if (config.resilience?.circuitBreaker?.failureThreshold !== undefined) {\n if (config.resilience.circuitBreaker.failureThreshold < 1) {\n errors.push(\"resilience.circuitBreaker.failureThreshold must be at least 1\");\n }\n }\n\n if (config.resilience?.bulkhead?.maxConcurrent !== undefined) {\n if (config.resilience.bulkhead.maxConcurrent < 1) {\n errors.push(\"resilience.bulkhead.maxConcurrent must be at least 1\");\n }\n }\n\n if (config.resilience?.retry?.attempts !== undefined) {\n if (config.resilience.retry.attempts < 0) {\n errors.push(\"resilience.retry.attempts must be non-negative\");\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","/**\n * @parsrun/service - RPC Errors\n */\n\nimport { ParsError } from \"@parsrun/core\";\n\n/**\n * Base RPC error\n */\nexport class RpcError extends ParsError {\n public readonly retryable: boolean;\n public readonly retryAfter?: number;\n\n constructor(\n message: string,\n code: string,\n statusCode: number = 500,\n options?: {\n retryable?: boolean;\n retryAfter?: number;\n details?: Record<string, unknown>;\n }\n ) {\n super(message, code, statusCode, options?.details);\n this.name = \"RpcError\";\n this.retryable = options?.retryable ?? false;\n if (options?.retryAfter !== undefined) {\n this.retryAfter = options.retryAfter;\n }\n }\n}\n\n/**\n * Service not found error\n */\nexport class ServiceNotFoundError extends RpcError {\n constructor(serviceName: string) {\n super(`Service not found: ${serviceName}`, \"SERVICE_NOT_FOUND\", 404, {\n retryable: false,\n details: { service: serviceName },\n });\n this.name = \"ServiceNotFoundError\";\n }\n}\n\n/**\n * Method not found error\n */\nexport class MethodNotFoundError extends RpcError {\n constructor(serviceName: string, methodName: string) {\n super(\n `Method not found: ${serviceName}.${methodName}`,\n \"METHOD_NOT_FOUND\",\n 404,\n {\n retryable: false,\n details: { service: serviceName, method: methodName },\n }\n );\n this.name = \"MethodNotFoundError\";\n }\n}\n\n/**\n * Version mismatch error\n */\nexport class VersionMismatchError extends RpcError {\n constructor(serviceName: string, requested: string, available: string) {\n super(\n `Version mismatch for ${serviceName}: requested ${requested}, available ${available}`,\n \"VERSION_MISMATCH\",\n 400,\n {\n retryable: false,\n details: { service: serviceName, requested, available },\n }\n );\n this.name = \"VersionMismatchError\";\n }\n}\n\n/**\n * Timeout error\n */\nexport class TimeoutError extends RpcError {\n constructor(serviceName: string, methodName: string, timeoutMs: number) {\n super(\n `Request to ${serviceName}.${methodName} timed out after ${timeoutMs}ms`,\n \"TIMEOUT\",\n 504,\n {\n retryable: true,\n details: { service: serviceName, method: methodName, timeout: timeoutMs },\n }\n );\n this.name = \"TimeoutError\";\n }\n}\n\n/**\n * Circuit breaker open error\n */\nexport class CircuitOpenError extends RpcError {\n constructor(serviceName: string, resetAfterMs: number) {\n super(\n `Circuit breaker open for ${serviceName}`,\n \"CIRCUIT_OPEN\",\n 503,\n {\n retryable: true,\n retryAfter: Math.ceil(resetAfterMs / 1000),\n details: { service: serviceName, resetAfterMs },\n }\n );\n this.name = \"CircuitOpenError\";\n }\n}\n\n/**\n * Bulkhead rejected error\n */\nexport class BulkheadRejectedError extends RpcError {\n constructor(serviceName: string) {\n super(\n `Request rejected by bulkhead for ${serviceName}: too many concurrent requests`,\n \"BULKHEAD_REJECTED\",\n 503,\n {\n retryable: true,\n retryAfter: 1,\n details: { service: serviceName },\n }\n );\n this.name = \"BulkheadRejectedError\";\n }\n}\n\n/**\n * Transport error\n */\nexport class TransportError extends RpcError {\n constructor(message: string, cause?: Error) {\n const options: { retryable: boolean; details?: Record<string, unknown> } = {\n retryable: true,\n };\n if (cause) {\n options.details = { cause: cause.message };\n }\n super(message, \"TRANSPORT_ERROR\", 502, options);\n this.name = \"TransportError\";\n }\n}\n\n/**\n * Serialization error\n */\nexport class SerializationError extends RpcError {\n constructor(message: string, cause?: Error) {\n const options: { retryable: boolean; details?: Record<string, unknown> } = {\n retryable: false,\n };\n if (cause) {\n options.details = { cause: cause.message };\n }\n super(message, \"SERIALIZATION_ERROR\", 400, options);\n this.name = \"SerializationError\";\n }\n}\n\n/**\n * Convert unknown error to RpcError\n */\nexport function toRpcError(error: unknown): RpcError {\n if (error instanceof RpcError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new RpcError(error.message, \"INTERNAL_ERROR\", 500, {\n retryable: false,\n details: { originalError: error.name },\n });\n }\n\n return new RpcError(String(error), \"UNKNOWN_ERROR\", 500, {\n retryable: false,\n });\n}\n","/**\n * @parsrun/service - Circuit Breaker\n * Prevents cascading failures by failing fast when a service is unhealthy\n */\n\nimport { CircuitOpenError } from \"../rpc/errors.js\";\n\n// ============================================================================\n// CIRCUIT BREAKER\n// ============================================================================\n\nexport interface CircuitBreakerOptions {\n /** Number of failures before opening circuit */\n failureThreshold: number;\n /** Time to wait before half-open state (ms) */\n resetTimeout: number;\n /** Number of successes in half-open to close circuit */\n successThreshold: number;\n /** Optional callback on state change */\n onStateChange?: (from: CircuitState, to: CircuitState) => void;\n}\n\nexport type CircuitState = \"closed\" | \"open\" | \"half-open\";\n\n/**\n * Circuit Breaker implementation\n *\n * States:\n * - CLOSED: Normal operation, requests pass through\n * - OPEN: Failing fast, requests are rejected immediately\n * - HALF-OPEN: Testing if service recovered, limited requests allowed\n */\nexport class CircuitBreaker {\n private _state: CircuitState = \"closed\";\n private failures = 0;\n private successes = 0;\n private lastFailureTime = 0;\n private readonly options: CircuitBreakerOptions;\n\n constructor(options: CircuitBreakerOptions) {\n this.options = options;\n }\n\n /**\n * Get current state\n */\n get state(): CircuitState {\n // Check if we should transition from open to half-open\n if (this._state === \"open\") {\n const timeSinceFailure = Date.now() - this.lastFailureTime;\n if (timeSinceFailure >= this.options.resetTimeout) {\n this.transitionTo(\"half-open\");\n }\n }\n return this._state;\n }\n\n /**\n * Execute a function with circuit breaker protection\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n // Check state (this may transition from open to half-open)\n const currentState = this.state;\n\n if (currentState === \"open\") {\n const resetAfter = this.options.resetTimeout - (Date.now() - this.lastFailureTime);\n throw new CircuitOpenError(\"service\", Math.max(0, resetAfter));\n }\n\n try {\n const result = await fn();\n this.onSuccess();\n return result;\n } catch (error) {\n this.onFailure();\n throw error;\n }\n }\n\n /**\n * Record a successful call\n */\n private onSuccess(): void {\n if (this._state === \"half-open\") {\n this.successes++;\n if (this.successes >= this.options.successThreshold) {\n this.transitionTo(\"closed\");\n }\n } else if (this._state === \"closed\") {\n // Reset failure count on success\n this.failures = 0;\n }\n }\n\n /**\n * Record a failed call\n */\n private onFailure(): void {\n this.lastFailureTime = Date.now();\n\n if (this._state === \"half-open\") {\n // Any failure in half-open goes back to open\n this.transitionTo(\"open\");\n } else if (this._state === \"closed\") {\n this.failures++;\n if (this.failures >= this.options.failureThreshold) {\n this.transitionTo(\"open\");\n }\n }\n }\n\n /**\n * Transition to a new state\n */\n private transitionTo(newState: CircuitState): void {\n const oldState = this._state;\n this._state = newState;\n\n // Reset counters on state change\n if (newState === \"closed\") {\n this.failures = 0;\n this.successes = 0;\n } else if (newState === \"half-open\") {\n this.successes = 0;\n }\n\n this.options.onStateChange?.(oldState, newState);\n }\n\n /**\n * Manually reset the circuit breaker\n */\n reset(): void {\n this.transitionTo(\"closed\");\n }\n\n /**\n * Get circuit breaker statistics\n */\n getStats(): {\n state: CircuitState;\n failures: number;\n successes: number;\n lastFailureTime: number;\n } {\n return {\n state: this.state,\n failures: this.failures,\n successes: this.successes,\n lastFailureTime: this.lastFailureTime,\n };\n }\n}\n","/**\n * @parsrun/service - Bulkhead\n * Limits concurrent requests to prevent resource exhaustion\n */\n\nimport { BulkheadRejectedError } from \"../rpc/errors.js\";\n\n// ============================================================================\n// BULKHEAD\n// ============================================================================\n\nexport interface BulkheadOptions {\n /** Maximum concurrent requests */\n maxConcurrent: number;\n /** Maximum queue size (0 = no queue) */\n maxQueue: number;\n /** Optional callback when request is rejected */\n onRejected?: () => void;\n}\n\ninterface QueuedRequest<T> {\n fn: () => Promise<T>;\n resolve: (value: T) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * Bulkhead implementation\n *\n * Limits the number of concurrent requests to protect resources.\n * Excess requests can be queued up to maxQueue limit.\n */\nexport class Bulkhead {\n private _concurrent = 0;\n private readonly queue: QueuedRequest<unknown>[] = [];\n private readonly options: BulkheadOptions;\n\n constructor(options: BulkheadOptions) {\n this.options = options;\n }\n\n /**\n * Get current concurrent count\n */\n get concurrent(): number {\n return this._concurrent;\n }\n\n /**\n * Get current queue size\n */\n get queued(): number {\n return this.queue.length;\n }\n\n /**\n * Check if bulkhead is full\n */\n get isFull(): boolean {\n return (\n this._concurrent >= this.options.maxConcurrent &&\n this.queue.length >= this.options.maxQueue\n );\n }\n\n /**\n * Execute a function with bulkhead protection\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n // Check if we can execute immediately\n if (this._concurrent < this.options.maxConcurrent) {\n return this.doExecute(fn);\n }\n\n // Check if we can queue\n if (this.queue.length < this.options.maxQueue) {\n return this.enqueue(fn);\n }\n\n // Reject\n this.options.onRejected?.();\n throw new BulkheadRejectedError(\"service\");\n }\n\n /**\n * Execute immediately\n */\n private async doExecute<T>(fn: () => Promise<T>): Promise<T> {\n this._concurrent++;\n try {\n return await fn();\n } finally {\n this._concurrent--;\n this.processQueue();\n }\n }\n\n /**\n * Add to queue\n */\n private enqueue<T>(fn: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n this.queue.push({\n fn,\n resolve: resolve as (value: unknown) => void,\n reject,\n });\n });\n }\n\n /**\n * Process queued requests\n */\n private processQueue(): void {\n if (this.queue.length === 0) return;\n if (this._concurrent >= this.options.maxConcurrent) return;\n\n const queued = this.queue.shift();\n if (!queued) return;\n\n this.doExecute(queued.fn)\n .then(queued.resolve)\n .catch(queued.reject);\n }\n\n /**\n * Get bulkhead statistics\n */\n getStats(): {\n concurrent: number;\n queued: number;\n maxConcurrent: number;\n maxQueue: number;\n } {\n return {\n concurrent: this._concurrent,\n queued: this.queue.length,\n maxConcurrent: this.options.maxConcurrent,\n maxQueue: this.options.maxQueue,\n };\n }\n\n /**\n * Clear the queue (reject all pending)\n */\n clearQueue(): void {\n const error = new BulkheadRejectedError(\"service\");\n while (this.queue.length > 0) {\n const queued = this.queue.shift();\n queued?.reject(error);\n }\n }\n}\n","/**\n * @parsrun/service - Retry\n * Retry failed operations with backoff\n */\n\n// ============================================================================\n// RETRY\n// ============================================================================\n\nexport interface RetryOptions {\n /** Number of retry attempts (not including initial attempt) */\n attempts: number;\n /** Backoff strategy */\n backoff: \"linear\" | \"exponential\";\n /** Initial delay in ms */\n initialDelay: number;\n /** Maximum delay in ms */\n maxDelay: number;\n /** Jitter factor (0-1) to add randomness */\n jitter?: number;\n /** Should retry predicate */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n /** Callback on retry */\n onRetry?: (error: unknown, attempt: number, delay: number) => void;\n}\n\n/**\n * Default retry predicate - retry on retryable errors\n */\nconst defaultShouldRetry = (error: unknown): boolean => {\n if (error && typeof error === \"object\" && \"retryable\" in error) {\n return (error as { retryable: boolean }).retryable;\n }\n return false;\n};\n\n/**\n * Calculate delay for retry attempt\n */\nfunction calculateDelay(\n attempt: number,\n options: RetryOptions\n): number {\n let delay: number;\n\n if (options.backoff === \"exponential\") {\n // Exponential backoff: initialDelay * 2^attempt\n delay = options.initialDelay * Math.pow(2, attempt);\n } else {\n // Linear backoff: initialDelay * (attempt + 1)\n delay = options.initialDelay * (attempt + 1);\n }\n\n // Apply max delay\n delay = Math.min(delay, options.maxDelay);\n\n // Apply jitter\n if (options.jitter && options.jitter > 0) {\n const jitterRange = delay * options.jitter;\n delay = delay - jitterRange / 2 + Math.random() * jitterRange;\n }\n\n return Math.round(delay);\n}\n\n/**\n * Sleep for a given duration\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Wrap a function with retry logic\n */\nexport function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): () => Promise<T> {\n const shouldRetry = options.shouldRetry ?? defaultShouldRetry;\n\n return async (): Promise<T> => {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= options.attempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Check if we should retry\n if (attempt >= options.attempts || !shouldRetry(error, attempt)) {\n throw error;\n }\n\n // Calculate delay\n const delay = calculateDelay(attempt, options);\n\n // Callback\n options.onRetry?.(error, attempt + 1, delay);\n\n // Wait before retry\n await sleep(delay);\n }\n }\n\n throw lastError;\n };\n}\n\n/**\n * Execute a function with retry\n */\nexport async function executeWithRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): Promise<T> {\n return withRetry(fn, options)();\n}\n\n/**\n * Create a retry wrapper with preset options\n */\nexport function createRetryWrapper(\n defaultOptions: Partial<RetryOptions>\n): <T>(fn: () => Promise<T>, options?: Partial<RetryOptions>) => Promise<T> {\n const defaults: RetryOptions = {\n attempts: defaultOptions.attempts ?? 3,\n backoff: defaultOptions.backoff ?? \"exponential\",\n initialDelay: defaultOptions.initialDelay ?? 100,\n maxDelay: defaultOptions.maxDelay ?? 10_000,\n jitter: defaultOptions.jitter ?? 0.1,\n };\n\n if (defaultOptions.shouldRetry) {\n defaults.shouldRetry = defaultOptions.shouldRetry;\n }\n if (defaultOptions.onRetry) {\n defaults.onRetry = defaultOptions.onRetry;\n }\n\n return async <T>(\n fn: () => Promise<T>,\n options?: Partial<RetryOptions>\n ): Promise<T> => {\n return executeWithRetry(fn, { ...defaults, ...options });\n };\n}\n","/**\n * @parsrun/service - Timeout\n * Timeout wrapper for async operations\n */\n\n// ============================================================================\n// TIMEOUT\n// ============================================================================\n\n/**\n * Timeout error\n */\nexport class TimeoutExceededError extends Error {\n readonly timeout: number;\n\n constructor(timeout: number) {\n super(`Operation timed out after ${timeout}ms`);\n this.name = \"TimeoutExceededError\";\n this.timeout = timeout;\n }\n}\n\n/**\n * Wrap a function with timeout\n */\nexport function withTimeout<T>(\n fn: () => Promise<T>,\n timeoutMs: number,\n onTimeout?: () => void | never\n): () => Promise<T> {\n return async (): Promise<T> => {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (onTimeout) {\n try {\n onTimeout();\n } catch (error) {\n reject(error);\n return;\n }\n }\n reject(new TimeoutExceededError(timeoutMs));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([fn(), timeoutPromise]);\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n };\n}\n\n/**\n * Execute a function with timeout\n */\nexport async function executeWithTimeout<T>(\n fn: () => Promise<T>,\n timeoutMs: number,\n onTimeout?: () => void | never\n): Promise<T> {\n return withTimeout(fn, timeoutMs, onTimeout)();\n}\n\n/**\n * Create a timeout wrapper with preset duration\n */\nexport function createTimeoutWrapper(\n defaultTimeoutMs: number\n): <T>(fn: () => Promise<T>, timeoutMs?: number) => Promise<T> {\n return async <T>(fn: () => Promise<T>, timeoutMs?: number): Promise<T> => {\n return executeWithTimeout(fn, timeoutMs ?? defaultTimeoutMs);\n };\n}\n\n/**\n * Race multiple promises with a timeout\n */\nexport async function raceWithTimeout<T>(\n promises: Promise<T>[],\n timeoutMs: number\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new TimeoutExceededError(timeoutMs));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([...promises, timeoutPromise]);\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n}\n\n/**\n * Execute with deadline (absolute time)\n */\nexport async function executeWithDeadline<T>(\n fn: () => Promise<T>,\n deadline: Date\n): Promise<T> {\n const now = Date.now();\n const deadlineMs = deadline.getTime();\n const timeoutMs = Math.max(0, deadlineMs - now);\n\n if (timeoutMs === 0) {\n throw new TimeoutExceededError(0);\n }\n\n return executeWithTimeout(fn, timeoutMs);\n}\n","/**\n * @parsrun/service - RPC Server\n * Server for handling RPC requests\n */\n\nimport type { Logger } from \"@parsrun/core\";\nimport { createLogger } from \"@parsrun/core\";\nimport type {\n RpcRequest,\n RpcResponse,\n ServiceDefinition,\n TraceContext,\n} from \"../types.js\";\nimport { satisfiesVersion, isMethodDeprecated, getMethodTimeout } from \"../define.js\";\nimport { MethodNotFoundError, VersionMismatchError, toRpcError } from \"./errors.js\";\n\n// ============================================================================\n// RPC HANDLER TYPES\n// ============================================================================\n\n/**\n * RPC handler context\n */\nexport interface RpcHandlerContext {\n /** Request ID */\n requestId: string;\n /** Service name */\n service: string;\n /** Method name */\n method: string;\n /** Method type */\n type: \"query\" | \"mutation\";\n /** Request metadata */\n metadata: Record<string, unknown>;\n /** Trace context */\n traceContext?: TraceContext;\n /** Logger */\n logger: Logger;\n}\n\n/**\n * RPC handler function\n */\nexport type RpcHandler<TInput = unknown, TOutput = unknown> = (\n input: TInput,\n context: RpcHandlerContext\n) => Promise<TOutput>;\n\n/**\n * RPC handlers record\n */\nexport type RpcHandlers = {\n queries?: Record<string, RpcHandler>;\n mutations?: Record<string, RpcHandler>;\n};\n\n// ============================================================================\n// RPC SERVER\n// ============================================================================\n\nexport interface RpcServerOptions {\n /** Service definition */\n definition: ServiceDefinition;\n /** RPC handlers */\n handlers: RpcHandlers;\n /** Logger */\n logger?: Logger;\n /** Default timeout in ms */\n defaultTimeout?: number;\n /** Middleware */\n middleware?: RpcMiddleware[];\n}\n\n/**\n * RPC middleware function\n */\nexport type RpcMiddleware = (\n request: RpcRequest,\n context: RpcHandlerContext,\n next: () => Promise<unknown>\n) => Promise<unknown>;\n\n/**\n * RPC Server for handling incoming requests\n */\nexport class RpcServer {\n private readonly definition: ServiceDefinition;\n private readonly handlers: RpcHandlers;\n private readonly logger: Logger;\n private readonly defaultTimeout: number;\n private readonly middleware: RpcMiddleware[];\n\n constructor(options: RpcServerOptions) {\n this.definition = options.definition;\n this.handlers = options.handlers;\n this.logger = options.logger ?? createLogger({ name: `rpc:${options.definition.name}` });\n this.defaultTimeout = options.defaultTimeout ?? 30_000;\n this.middleware = options.middleware ?? [];\n }\n\n /**\n * Handle an RPC request\n */\n async handle<TInput, TOutput>(request: RpcRequest<TInput>): Promise<RpcResponse<TOutput>> {\n const startTime = Date.now();\n const context: RpcHandlerContext = {\n requestId: request.id,\n service: request.service,\n method: request.method,\n type: request.type,\n metadata: request.metadata ?? {},\n logger: this.logger.child({ requestId: request.id, method: request.method }),\n };\n\n if (request.traceContext) {\n context.traceContext = request.traceContext;\n }\n\n try {\n // Check version compatibility\n if (request.version && !satisfiesVersion(this.definition.version, request.version)) {\n throw new VersionMismatchError(\n this.definition.name,\n request.version,\n this.definition.version\n );\n }\n\n // Get handler\n const handler = this.getHandler(request.method, request.type);\n if (!handler) {\n throw new MethodNotFoundError(this.definition.name, request.method);\n }\n\n // Check deprecation\n const deprecation = isMethodDeprecated(this.definition, request.method, request.type);\n if (deprecation.deprecated) {\n context.logger.warn(`Method ${request.method} is deprecated`, {\n since: deprecation.since,\n replacement: deprecation.replacement,\n });\n }\n\n // Build middleware chain\n const chain = this.buildMiddlewareChain(request, context, handler);\n\n // Execute with timeout\n const timeout = getMethodTimeout(\n this.definition,\n request.method,\n request.type,\n this.defaultTimeout\n );\n\n const output = await Promise.race([\n chain(),\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error(\"Handler timeout\")), timeout)\n ),\n ]);\n\n const duration = Date.now() - startTime;\n context.logger.info(`${request.type} ${request.method} completed`, { durationMs: duration });\n\n const successResponse: RpcResponse<TOutput> = {\n id: request.id,\n success: true,\n version: this.definition.version,\n output: output as TOutput,\n };\n if (request.traceContext) {\n successResponse.traceContext = request.traceContext;\n }\n return successResponse;\n } catch (error) {\n const duration = Date.now() - startTime;\n const rpcError = toRpcError(error);\n\n context.logger.error(`${request.type} ${request.method} failed`, error as Error, {\n durationMs: duration,\n errorCode: rpcError.code,\n });\n\n const errorData: RpcResponse<TOutput>[\"error\"] = {\n code: rpcError.code,\n message: rpcError.message,\n retryable: rpcError.retryable,\n };\n if (rpcError.details) {\n errorData!.details = rpcError.details;\n }\n if (rpcError.retryAfter !== undefined) {\n errorData!.retryAfter = rpcError.retryAfter;\n }\n\n const errorResponse: RpcResponse<TOutput> = {\n id: request.id,\n success: false,\n version: this.definition.version,\n error: errorData,\n };\n if (request.traceContext) {\n errorResponse.traceContext = request.traceContext;\n }\n return errorResponse;\n }\n }\n\n /**\n * Get handler for a method\n */\n private getHandler(method: string, type: \"query\" | \"mutation\"): RpcHandler | undefined {\n const handlers = type === \"query\" ? this.handlers.queries : this.handlers.mutations;\n return handlers?.[method];\n }\n\n /**\n * Build middleware chain\n */\n private buildMiddlewareChain(\n request: RpcRequest,\n context: RpcHandlerContext,\n handler: RpcHandler\n ): () => Promise<unknown> {\n let index = -1;\n\n const dispatch = async (i: number): Promise<unknown> => {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n\n if (i < this.middleware.length) {\n const mw = this.middleware[i]!;\n return mw(request, context, () => dispatch(i + 1));\n }\n\n return handler(request.input, context);\n };\n\n return () => dispatch(0);\n }\n\n /**\n * Get service definition\n */\n getDefinition(): ServiceDefinition {\n return this.definition;\n }\n\n /**\n * Get registered methods\n */\n getMethods(): { queries: string[]; mutations: string[] } {\n return {\n queries: Object.keys(this.handlers.queries ?? {}),\n mutations: Object.keys(this.handlers.mutations ?? {}),\n };\n }\n}\n\n/**\n * Create an RPC server\n */\nexport function createRpcServer(options: RpcServerOptions): RpcServer {\n return new RpcServer(options);\n}\n\n// ============================================================================\n// BUILT-IN MIDDLEWARE\n// ============================================================================\n\n/**\n * Logging middleware\n */\nexport function loggingMiddleware(): RpcMiddleware {\n return async (request, context, next) => {\n context.logger.debug(`Handling ${request.type} ${request.method}`, {\n inputKeys: Object.keys(request.input as object),\n });\n\n const result = await next();\n\n context.logger.debug(`Completed ${request.type} ${request.method}`);\n\n return result;\n };\n}\n\n/**\n * Validation middleware (placeholder - integrate with ArkType)\n */\nexport function validationMiddleware(\n validators: Record<string, (input: unknown) => unknown>\n): RpcMiddleware {\n return async (request, _context, next) => {\n const validator = validators[request.method];\n if (validator) {\n request.input = validator(request.input);\n }\n return next();\n };\n}\n\n/**\n * Tenant context middleware\n */\nexport function tenantMiddleware(): RpcMiddleware {\n return async (_request, context, next) => {\n const tenantId = context.metadata[\"tenantId\"];\n if (tenantId) {\n context.logger = context.logger.child({ tenantId });\n }\n return next();\n };\n}\n","/**\n * @parsrun/service - Service Definition\n * Factory function for defining services\n */\n\nimport type {\n ServiceDefinition,\n QueryDefinition,\n MutationDefinition,\n EventDefinition,\n} from \"./types.js\";\n\n// ============================================================================\n// SERVICE DEFINITION FACTORY\n// ============================================================================\n\n/**\n * Define a service with type-safe queries, mutations, and events\n *\n * @example\n * ```typescript\n * const paymentsService = defineService({\n * name: 'payments',\n * version: '1.0.0',\n *\n * queries: {\n * getSubscription: {\n * input: { subscriptionId: 'string' },\n * output: { status: 'string', plan: 'string' },\n * },\n * },\n *\n * mutations: {\n * subscribe: {\n * input: { email: 'string', planId: 'string' },\n * output: { checkoutUrl: 'string' },\n * },\n * },\n *\n * events: {\n * emits: {\n * 'subscription.created': {\n * data: { customerId: 'string', planId: 'string' },\n * delivery: 'at-least-once',\n * },\n * },\n * handles: ['user.deleted', 'tenant.suspended'],\n * },\n * });\n * ```\n */\nexport function defineService<\n TQueries extends Record<string, QueryDefinition> = Record<string, QueryDefinition>,\n TMutations extends Record<string, MutationDefinition> = Record<string, MutationDefinition>,\n TEmits extends Record<string, EventDefinition> = Record<string, EventDefinition>,\n THandles extends string[] = string[],\n>(\n definition: ServiceDefinition<TQueries, TMutations, TEmits, THandles>\n): ServiceDefinition<TQueries, TMutations, TEmits, THandles> {\n // Validate service definition\n validateServiceDefinition(definition);\n\n // Freeze the definition to prevent mutation\n return Object.freeze({\n ...definition,\n queries: definition.queries ? Object.freeze({ ...definition.queries }) : undefined,\n mutations: definition.mutations ? Object.freeze({ ...definition.mutations }) : undefined,\n events: definition.events\n ? Object.freeze({\n emits: definition.events.emits\n ? Object.freeze({ ...definition.events.emits })\n : undefined,\n handles: definition.events.handles\n ? Object.freeze([...definition.events.handles])\n : undefined,\n })\n : undefined,\n }) as ServiceDefinition<TQueries, TMutations, TEmits, THandles>;\n}\n\n/**\n * Validate service definition\n */\nfunction validateServiceDefinition(definition: ServiceDefinition): void {\n if (!definition.name) {\n throw new Error(\"Service name is required\");\n }\n\n if (!definition.version) {\n throw new Error(\"Service version is required\");\n }\n\n // Validate version format (semver-like)\n const versionRegex = /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?$/;\n if (!versionRegex.test(definition.version)) {\n throw new Error(`Invalid version format: ${definition.version}. Expected semver (e.g., 1.0.0)`);\n }\n\n // Validate query/mutation names (no dots or special chars)\n const nameRegex = /^[a-zA-Z][a-zA-Z0-9_]*$/;\n\n if (definition.queries) {\n for (const name of Object.keys(definition.queries)) {\n if (!nameRegex.test(name)) {\n throw new Error(\n `Invalid query name: ${name}. Must start with letter and contain only alphanumeric and underscore`\n );\n }\n }\n }\n\n if (definition.mutations) {\n for (const name of Object.keys(definition.mutations)) {\n if (!nameRegex.test(name)) {\n throw new Error(\n `Invalid mutation name: ${name}. Must start with letter and contain only alphanumeric and underscore`\n );\n }\n }\n }\n\n // Validate event names (dot notation allowed)\n const eventNameRegex = /^[a-zA-Z][a-zA-Z0-9_.]*$/;\n\n if (definition.events?.emits) {\n for (const name of Object.keys(definition.events.emits)) {\n if (!eventNameRegex.test(name)) {\n throw new Error(\n `Invalid event name: ${name}. Must start with letter and contain only alphanumeric, underscore, and dot`\n );\n }\n }\n }\n\n if (definition.events?.handles) {\n for (const name of definition.events.handles) {\n if (!eventNameRegex.test(name)) {\n throw new Error(\n `Invalid handled event name: ${name}. Must start with letter and contain only alphanumeric, underscore, and dot`\n );\n }\n }\n }\n}\n\n// ============================================================================\n// SERVICE DEFINITION UTILITIES\n// ============================================================================\n\n/**\n * Get all method names from a service definition\n */\nexport function getServiceMethods(definition: ServiceDefinition): {\n queries: string[];\n mutations: string[];\n} {\n return {\n queries: definition.queries ? Object.keys(definition.queries) : [],\n mutations: definition.mutations ? Object.keys(definition.mutations) : [],\n };\n}\n\n/**\n * Get all event types from a service definition\n */\nexport function getServiceEvents(definition: ServiceDefinition): {\n emits: string[];\n handles: string[];\n} {\n return {\n emits: definition.events?.emits ? Object.keys(definition.events.emits) : [],\n handles: definition.events?.handles ?? [],\n };\n}\n\n/**\n * Check if a service version satisfies a version requirement\n *\n * @example\n * ```typescript\n * satisfiesVersion('1.2.3', '1.x') // true\n * satisfiesVersion('1.2.3', '1.2.x') // true\n * satisfiesVersion('2.0.0', '1.x') // false\n * ```\n */\nexport function satisfiesVersion(version: string, requirement: string): boolean {\n const versionParts = version.split(\".\").map((p) => parseInt(p, 10));\n const requirementParts = requirement.split(\".\");\n\n for (let i = 0; i < requirementParts.length; i++) {\n const req = requirementParts[i];\n if (req === \"x\" || req === \"*\") {\n continue;\n }\n\n const reqNum = parseInt(req ?? \"0\", 10);\n const verNum = versionParts[i] ?? 0;\n\n if (verNum !== reqNum) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check if a method is deprecated in the service definition\n */\nexport function isMethodDeprecated(\n definition: ServiceDefinition,\n methodName: string,\n type: \"query\" | \"mutation\"\n): { deprecated: boolean; since?: string; replacement?: string } {\n const methods = type === \"query\" ? definition.queries : definition.mutations;\n const method = methods?.[methodName];\n\n if (!method?.deprecated) {\n return { deprecated: false };\n }\n\n const result: { deprecated: boolean; since?: string; replacement?: string } = {\n deprecated: true,\n since: method.deprecated,\n };\n\n if (method.replacement) {\n result.replacement = method.replacement;\n }\n\n return result;\n}\n\n/**\n * Get method timeout (use method-specific or fall back to default)\n */\nexport function getMethodTimeout(\n definition: ServiceDefinition,\n methodName: string,\n type: \"query\" | \"mutation\",\n defaultTimeout: number\n): number {\n const methods = type === \"query\" ? definition.queries : definition.mutations;\n const method = methods?.[methodName];\n\n return method?.timeout ?? defaultTimeout;\n}\n","/**\n * @parsrun/service - Embedded RPC Transport\n * Direct function call transport for monolithic/embedded mode\n */\n\nimport type { RpcRequest, RpcResponse, RpcTransport } from \"../../types.js\";\nimport type { RpcServer } from \"../server.js\";\n\n// ============================================================================\n// EMBEDDED TRANSPORT\n// ============================================================================\n\n/**\n * Embedded transport that calls handlers directly\n * Used when services are in the same process\n */\nexport class EmbeddedTransport implements RpcTransport {\n readonly name = \"embedded\";\n private readonly server: RpcServer;\n\n constructor(server: RpcServer) {\n this.server = server;\n }\n\n async call<TInput, TOutput>(request: RpcRequest<TInput>): Promise<RpcResponse<TOutput>> {\n // Direct call to server - no serialization needed\n return this.server.handle<TInput, TOutput>(request);\n }\n\n async close(): Promise<void> {\n // No cleanup needed for embedded transport\n }\n}\n\n/**\n * Create an embedded transport\n */\nexport function createEmbeddedTransport(server: RpcServer): EmbeddedTransport {\n return new EmbeddedTransport(server);\n}\n\n// ============================================================================\n// EMBEDDED TRANSPORT REGISTRY\n// ============================================================================\n\n/**\n * Registry for embedded services\n * Allows services to find each other in embedded mode\n */\nexport class EmbeddedRegistry {\n private static instance: EmbeddedRegistry | null = null;\n private readonly servers: Map<string, RpcServer> = new Map();\n\n private constructor() {}\n\n static getInstance(): EmbeddedRegistry {\n if (!EmbeddedRegistry.instance) {\n EmbeddedRegistry.instance = new EmbeddedRegistry();\n }\n return EmbeddedRegistry.instance;\n }\n\n /**\n * Register a service\n */\n register(name: string, server: RpcServer): void {\n if (this.servers.has(name)) {\n throw new Error(`Service already registered: ${name}`);\n }\n this.servers.set(name, server);\n }\n\n /**\n * Unregister a service\n */\n unregister(name: string): boolean {\n return this.servers.delete(name);\n }\n\n /**\n * Get a service by name\n */\n get(name: string): RpcServer | undefined {\n return this.servers.get(name);\n }\n\n /**\n * Check if a service is registered\n */\n has(name: string): boolean {\n return this.servers.has(name);\n }\n\n /**\n * Get all registered service names\n */\n getServiceNames(): string[] {\n return Array.from(this.servers.keys());\n }\n\n /**\n * Create a transport for a registered service\n */\n createTransport(name: string): EmbeddedTransport {\n const server = this.servers.get(name);\n if (!server) {\n throw new Error(`Service not found: ${name}`);\n }\n return new EmbeddedTransport(server);\n }\n\n /**\n * Clear all registered services\n */\n clear(): void {\n this.servers.clear();\n }\n\n /**\n * Reset the singleton instance (for testing)\n */\n static reset(): void {\n EmbeddedRegistry.instance = null;\n }\n}\n\n/**\n * Get the global embedded registry\n */\nexport function getEmbeddedRegistry(): EmbeddedRegistry {\n return EmbeddedRegistry.getInstance();\n}\n","/**\n * @parsrun/service - Serialization\n * JSON and MessagePack serializers\n */\n\n// ============================================================================\n// SERIALIZER INTERFACE\n// ============================================================================\n\n/**\n * Serializer interface for encoding/decoding data\n */\nexport interface Serializer {\n /** Encode data to string or buffer */\n encode(data: unknown): string | ArrayBuffer;\n /** Decode string or buffer to data */\n decode(raw: string | ArrayBuffer): unknown;\n /** Content type for HTTP headers */\n contentType: string;\n}\n\n// ============================================================================\n// JSON SERIALIZER\n// ============================================================================\n\n/**\n * JSON serializer (default)\n */\nexport const jsonSerializer: Serializer = {\n encode(data: unknown): string {\n return JSON.stringify(data);\n },\n\n decode(raw: string | ArrayBuffer): unknown {\n if (raw instanceof ArrayBuffer) {\n const decoder = new TextDecoder();\n return JSON.parse(decoder.decode(raw));\n }\n return JSON.parse(raw);\n },\n\n contentType: \"application/json\",\n};\n\n// ============================================================================\n// MESSAGEPACK SERIALIZER (Lightweight implementation)\n// ============================================================================\n\n/**\n * Lightweight MessagePack encoder\n * Supports: null, boolean, number, string, array, object\n */\nfunction msgpackEncode(value: unknown): Uint8Array {\n const parts: Uint8Array[] = [];\n\n function encode(val: unknown): void {\n if (val === null || val === undefined) {\n parts.push(new Uint8Array([0xc0])); // nil\n return;\n }\n\n if (typeof val === \"boolean\") {\n parts.push(new Uint8Array([val ? 0xc3 : 0xc2]));\n return;\n }\n\n if (typeof val === \"number\") {\n if (Number.isInteger(val)) {\n if (val >= 0 && val <= 127) {\n // positive fixint\n parts.push(new Uint8Array([val]));\n } else if (val < 0 && val >= -32) {\n // negative fixint\n parts.push(new Uint8Array([val & 0xff]));\n } else if (val >= 0 && val <= 0xff) {\n // uint8\n parts.push(new Uint8Array([0xcc, val]));\n } else if (val >= 0 && val <= 0xffff) {\n // uint16\n parts.push(new Uint8Array([0xcd, (val >> 8) & 0xff, val & 0xff]));\n } else if (val >= 0 && val <= 0xffffffff) {\n // uint32\n parts.push(\n new Uint8Array([\n 0xce,\n (val >> 24) & 0xff,\n (val >> 16) & 0xff,\n (val >> 8) & 0xff,\n val & 0xff,\n ])\n );\n } else if (val >= -128 && val <= 127) {\n // int8\n parts.push(new Uint8Array([0xd0, val & 0xff]));\n } else if (val >= -32768 && val <= 32767) {\n // int16\n parts.push(new Uint8Array([0xd1, (val >> 8) & 0xff, val & 0xff]));\n } else if (val >= -2147483648 && val <= 2147483647) {\n // int32\n parts.push(\n new Uint8Array([\n 0xd2,\n (val >> 24) & 0xff,\n (val >> 16) & 0xff,\n (val >> 8) & 0xff,\n val & 0xff,\n ])\n );\n } else {\n // Fall back to float64 for large integers\n const buffer = new ArrayBuffer(9);\n const view = new DataView(buffer);\n view.setUint8(0, 0xcb);\n view.setFloat64(1, val, false);\n parts.push(new Uint8Array(buffer));\n }\n } else {\n // float64\n const buffer = new ArrayBuffer(9);\n const view = new DataView(buffer);\n view.setUint8(0, 0xcb);\n view.setFloat64(1, val, false);\n parts.push(new Uint8Array(buffer));\n }\n return;\n }\n\n if (typeof val === \"string\") {\n const encoded = new TextEncoder().encode(val);\n const len = encoded.length;\n\n if (len <= 31) {\n // fixstr\n parts.push(new Uint8Array([0xa0 | len]));\n } else if (len <= 0xff) {\n // str8\n parts.push(new Uint8Array([0xd9, len]));\n } else if (len <= 0xffff) {\n // str16\n parts.push(new Uint8Array([0xda, (len >> 8) & 0xff, len & 0xff]));\n } else {\n // str32\n parts.push(\n new Uint8Array([\n 0xdb,\n (len >> 24) & 0xff,\n (len >> 16) & 0xff,\n (len >> 8) & 0xff,\n len & 0xff,\n ])\n );\n }\n parts.push(encoded);\n return;\n }\n\n if (Array.isArray(val)) {\n const len = val.length;\n\n if (len <= 15) {\n // fixarray\n parts.push(new Uint8Array([0x90 | len]));\n } else if (len <= 0xffff) {\n // array16\n parts.push(new Uint8Array([0xdc, (len >> 8) & 0xff, len & 0xff]));\n } else {\n // array32\n parts.push(\n new Uint8Array([\n 0xdd,\n (len >> 24) & 0xff,\n (len >> 16) & 0xff,\n (len >> 8) & 0xff,\n len & 0xff,\n ])\n );\n }\n\n for (const item of val) {\n encode(item);\n }\n return;\n }\n\n if (typeof val === \"object\") {\n const keys = Object.keys(val as object);\n const len = keys.length;\n\n if (len <= 15) {\n // fixmap\n parts.push(new Uint8Array([0x80 | len]));\n } else if (len <= 0xffff) {\n // map16\n parts.push(new Uint8Array([0xde, (len >> 8) & 0xff, len & 0xff]));\n } else {\n // map32\n parts.push(\n new Uint8Array([\n 0xdf,\n (len >> 24) & 0xff,\n (len >> 16) & 0xff,\n (len >> 8) & 0xff,\n len & 0xff,\n ])\n );\n }\n\n for (const key of keys) {\n encode(key);\n encode((val as Record<string, unknown>)[key]);\n }\n return;\n }\n\n // Unsupported type - encode as null\n parts.push(new Uint8Array([0xc0]));\n }\n\n encode(value);\n\n // Merge all parts\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n result.set(part, offset);\n offset += part.length;\n }\n\n return result;\n}\n\n/**\n * Lightweight MessagePack decoder\n */\nfunction msgpackDecode(buffer: Uint8Array): unknown {\n let offset = 0;\n\n function decode(): unknown {\n if (offset >= buffer.length) {\n throw new Error(\"Unexpected end of buffer\");\n }\n\n const byte = buffer[offset++]!;\n\n // Positive fixint (0x00 - 0x7f)\n if (byte <= 0x7f) {\n return byte;\n }\n\n // Negative fixint (0xe0 - 0xff)\n if (byte >= 0xe0) {\n return byte - 256;\n }\n\n // Fixmap (0x80 - 0x8f)\n if (byte >= 0x80 && byte <= 0x8f) {\n const len = byte - 0x80;\n const result: Record<string, unknown> = {};\n for (let i = 0; i < len; i++) {\n const key = decode() as string;\n result[key] = decode();\n }\n return result;\n }\n\n // Fixarray (0x90 - 0x9f)\n if (byte >= 0x90 && byte <= 0x9f) {\n const len = byte - 0x90;\n const result: unknown[] = [];\n for (let i = 0; i < len; i++) {\n result.push(decode());\n }\n return result;\n }\n\n // Fixstr (0xa0 - 0xbf)\n if (byte >= 0xa0 && byte <= 0xbf) {\n const len = byte - 0xa0;\n const str = new TextDecoder().decode(buffer.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n\n switch (byte) {\n case 0xc0: // nil\n return null;\n case 0xc2: // false\n return false;\n case 0xc3: // true\n return true;\n\n case 0xcc: // uint8\n return buffer[offset++];\n case 0xcd: // uint16\n return (buffer[offset++]! << 8) | buffer[offset++]!;\n case 0xce: // uint32\n return (\n ((buffer[offset++]! << 24) >>> 0) +\n (buffer[offset++]! << 16) +\n (buffer[offset++]! << 8) +\n buffer[offset++]!\n );\n\n case 0xd0: // int8\n {\n const val = buffer[offset++]!;\n return val > 127 ? val - 256 : val;\n }\n case 0xd1: // int16\n {\n const val = (buffer[offset++]! << 8) | buffer[offset++]!;\n return val > 32767 ? val - 65536 : val;\n }\n case 0xd2: // int32\n {\n const val =\n (buffer[offset++]! << 24) |\n (buffer[offset++]! << 16) |\n (buffer[offset++]! << 8) |\n buffer[offset++]!;\n return val;\n }\n\n case 0xcb: // float64\n {\n const view = new DataView(buffer.buffer, buffer.byteOffset + offset, 8);\n offset += 8;\n return view.getFloat64(0, false);\n }\n\n case 0xd9: // str8\n {\n const len = buffer[offset++]!;\n const str = new TextDecoder().decode(buffer.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n case 0xda: // str16\n {\n const len = (buffer[offset++]! << 8) | buffer[offset++]!;\n const str = new TextDecoder().decode(buffer.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n case 0xdb: // str32\n {\n const len =\n (buffer[offset++]! << 24) |\n (buffer[offset++]! << 16) |\n (buffer[offset++]! << 8) |\n buffer[offset++]!;\n const str = new TextDecoder().decode(buffer.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n\n case 0xdc: // array16\n {\n const len = (buffer[offset++]! << 8) | buffer[offset++]!;\n const result: unknown[] = [];\n for (let i = 0; i < len; i++) {\n result.push(decode());\n }\n return result;\n }\n case 0xdd: // array32\n {\n const len =\n (buffer[offset++]! << 24) |\n (buffer[offset++]! << 16) |\n (buffer[offset++]! << 8) |\n buffer[offset++]!;\n const result: unknown[] = [];\n for (let i = 0; i < len; i++) {\n result.push(decode());\n }\n return result;\n }\n\n case 0xde: // map16\n {\n const len = (buffer[offset++]! << 8) | buffer[offset++]!;\n const result: Record<string, unknown> = {};\n for (let i = 0; i < len; i++) {\n const key = decode() as string;\n result[key] = decode();\n }\n return result;\n }\n case 0xdf: // map32\n {\n const len =\n (buffer[offset++]! << 24) |\n (buffer[offset++]! << 16) |\n (buffer[offset++]! << 8) |\n buffer[offset++]!;\n const result: Record<string, unknown> = {};\n for (let i = 0; i < len; i++) {\n const key = decode() as string;\n result[key] = decode();\n }\n return result;\n }\n\n default:\n throw new Error(`Unknown MessagePack type: 0x${byte.toString(16)}`);\n }\n }\n\n return decode();\n}\n\n/**\n * MessagePack serializer\n */\nexport const msgpackSerializer: Serializer = {\n encode(data: unknown): ArrayBuffer {\n const encoded = msgpackEncode(data);\n // Create a new ArrayBuffer with the exact bytes from the Uint8Array\n const buffer = new ArrayBuffer(encoded.byteLength);\n new Uint8Array(buffer).set(encoded);\n return buffer;\n },\n\n decode(raw: string | ArrayBuffer): unknown {\n if (typeof raw === \"string\") {\n // If string is passed, assume it's base64 encoded\n const binary = atob(raw);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return msgpackDecode(bytes);\n }\n return msgpackDecode(new Uint8Array(raw));\n },\n\n contentType: \"application/msgpack\",\n};\n\n// ============================================================================\n// SERIALIZER FACTORY\n// ============================================================================\n\n/**\n * Get serializer by format name\n */\nexport function getSerializer(format: \"json\" | \"msgpack\"): Serializer {\n switch (format) {\n case \"json\":\n return jsonSerializer;\n case \"msgpack\":\n return msgpackSerializer;\n default:\n return jsonSerializer;\n }\n}\n\n/**\n * Create a custom serializer\n */\nexport function createSerializer(options: {\n encode: (data: unknown) => string | ArrayBuffer;\n decode: (raw: string | ArrayBuffer) => unknown;\n contentType: string;\n}): Serializer {\n return options;\n}\n","/**\n * @parsrun/service - HTTP RPC Transport\n * HTTP-based transport for distributed services\n */\n\nimport type { RpcRequest, RpcResponse, RpcTransport } from \"../../types.js\";\nimport { type Serializer, jsonSerializer } from \"../../serialization/index.js\";\nimport { TransportError, SerializationError } from \"../errors.js\";\n\n// ============================================================================\n// HTTP TRANSPORT\n// ============================================================================\n\nexport interface HttpTransportOptions {\n /** Base URL of the service */\n baseUrl: string;\n /** Custom serializer (default: JSON) */\n serializer?: Serializer;\n /** Custom headers */\n headers?: Record<string, string>;\n /** Fetch function (for testing or custom implementations) */\n fetch?: typeof globalThis.fetch;\n /** Request timeout in ms */\n timeout?: number;\n}\n\n/**\n * HTTP transport for RPC calls\n */\nexport class HttpTransport implements RpcTransport {\n readonly name = \"http\";\n private readonly baseUrl: string;\n private readonly serializer: Serializer;\n private readonly headers: Record<string, string>;\n private readonly fetchFn: typeof globalThis.fetch;\n private readonly timeout: number;\n\n constructor(options: HttpTransportOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\"); // Remove trailing slash\n this.serializer = options.serializer ?? jsonSerializer;\n this.headers = options.headers ?? {};\n this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.timeout = options.timeout ?? 30_000;\n }\n\n async call<TInput, TOutput>(request: RpcRequest<TInput>): Promise<RpcResponse<TOutput>> {\n const url = `${this.baseUrl}/rpc`;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n // Serialize request\n let body: string | ArrayBuffer;\n try {\n body = this.serializer.encode(request);\n } catch (error) {\n throw new SerializationError(\n \"Failed to serialize request\",\n error instanceof Error ? error : undefined\n );\n }\n\n // Make HTTP request\n const response = await this.fetchFn(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": this.serializer.contentType,\n Accept: this.serializer.contentType,\n \"X-Request-ID\": request.id,\n \"X-Service\": request.service,\n \"X-Method\": request.method,\n \"X-Method-Type\": request.type,\n ...(request.version ? { \"X-Service-Version\": request.version } : {}),\n ...(request.traceContext\n ? {\n traceparent: formatTraceparent(request.traceContext),\n ...(request.traceContext.traceState\n ? { tracestate: request.traceContext.traceState }\n : {}),\n }\n : {}),\n ...this.headers,\n },\n body: body instanceof ArrayBuffer ? body : body,\n signal: controller.signal,\n });\n\n // Parse response\n let responseData: RpcResponse<TOutput>;\n try {\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n if (contentType.includes(\"msgpack\")) {\n const buffer = await response.arrayBuffer();\n responseData = this.serializer.decode(buffer) as RpcResponse<TOutput>;\n } else {\n const text = await response.text();\n responseData = this.serializer.decode(text) as RpcResponse<TOutput>;\n }\n } catch (error) {\n throw new SerializationError(\n \"Failed to deserialize response\",\n error instanceof Error ? error : undefined\n );\n }\n\n return responseData;\n } catch (error) {\n if (error instanceof SerializationError) {\n throw error;\n }\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n throw new TransportError(`Request timeout after ${this.timeout}ms`);\n }\n throw new TransportError(`HTTP request failed: ${error.message}`, error);\n }\n\n throw new TransportError(\"Unknown transport error\");\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async close(): Promise<void> {\n // No persistent connection to close\n }\n}\n\n/**\n * Create an HTTP transport\n */\nexport function createHttpTransport(options: HttpTransportOptions): HttpTransport {\n return new HttpTransport(options);\n}\n\n// ============================================================================\n// TRACE CONTEXT HELPERS\n// ============================================================================\n\nimport type { TraceContext } from \"../../types.js\";\n\n/**\n * Format trace context as W3C traceparent header\n */\nfunction formatTraceparent(ctx: TraceContext): string {\n const flags = ctx.traceFlags.toString(16).padStart(2, \"0\");\n return `00-${ctx.traceId}-${ctx.spanId}-${flags}`;\n}\n\n/**\n * Parse W3C traceparent header\n */\nexport function parseTraceparent(header: string): TraceContext | null {\n const parts = header.split(\"-\");\n if (parts.length !== 4) {\n return null;\n }\n\n const [version, traceId, spanId, flags] = parts;\n if (version !== \"00\" || !traceId || !spanId || !flags) {\n return null;\n }\n\n if (traceId.length !== 32 || spanId.length !== 16 || flags.length !== 2) {\n return null;\n }\n\n return {\n traceId,\n spanId,\n traceFlags: parseInt(flags, 16),\n };\n}\n\n// ============================================================================\n// HTTP SERVER ADAPTER\n// ============================================================================\n\nimport type { RpcServer } from \"../server.js\";\n\n/**\n * Create HTTP request handler for RPC server\n * Can be used with Hono, Express, or any HTTP framework\n */\nexport function createHttpHandler(server: RpcServer) {\n return async (request: Request): Promise<Response> => {\n try {\n // Parse request body\n const contentType = request.headers.get(\"Content-Type\") ?? \"application/json\";\n let body: unknown;\n\n if (contentType.includes(\"msgpack\")) {\n const buffer = await request.arrayBuffer();\n // For msgpack, we'd need to decode - using JSON for now\n body = JSON.parse(new TextDecoder().decode(buffer));\n } else {\n body = await request.json();\n }\n\n const rpcRequest = body as RpcRequest;\n\n // Parse trace context\n const traceparent = request.headers.get(\"traceparent\");\n if (traceparent) {\n const traceContext = parseTraceparent(traceparent);\n if (traceContext) {\n const tracestate = request.headers.get(\"tracestate\");\n if (tracestate) {\n traceContext.traceState = tracestate;\n }\n rpcRequest.traceContext = traceContext;\n }\n }\n\n // Handle request\n const response = await server.handle(rpcRequest);\n\n // Return response\n return new Response(JSON.stringify(response), {\n status: response.success ? 200 : getHttpStatus(response.error?.code),\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Request-ID\": rpcRequest.id,\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return new Response(\n JSON.stringify({\n success: false,\n error: {\n code: \"INTERNAL_ERROR\",\n message,\n },\n }),\n {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n }\n );\n }\n };\n}\n\n/**\n * Map error code to HTTP status\n */\nfunction getHttpStatus(code?: string): number {\n switch (code) {\n case \"METHOD_NOT_FOUND\":\n case \"SERVICE_NOT_FOUND\":\n return 404;\n case \"VERSION_MISMATCH\":\n case \"VALIDATION_ERROR\":\n case \"SERIALIZATION_ERROR\":\n return 400;\n case \"UNAUTHORIZED\":\n return 401;\n case \"FORBIDDEN\":\n return 403;\n case \"TIMEOUT\":\n return 504;\n case \"CIRCUIT_OPEN\":\n case \"BULKHEAD_REJECTED\":\n return 503;\n default:\n return 500;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/rpc/client.ts","../../src/config.ts","../../src/rpc/errors.ts","../../src/resilience/circuit-breaker.ts","../../src/resilience/bulkhead.ts","../../src/resilience/retry.ts","../../src/resilience/timeout.ts","../../src/rpc/server.ts","../../src/define.ts","../../src/rpc/transports/embedded.ts","../../src/serialization/index.ts","../../src/rpc/transports/http.ts"],"sourcesContent":["/**\n * @parsrun/service - RPC Client\n * Client for making RPC calls to services\n */\n\nimport { generateId } from \"@parsrun/core\";\nimport type {\n RpcRequest,\n RpcTransport,\n RpcMetadata,\n TraceContext,\n ServiceConfig,\n} from \"../types.js\";\nimport { mergeConfig } from \"../config.js\";\nimport { TimeoutError, toRpcError } from \"./errors.js\";\nimport {\n CircuitBreaker,\n Bulkhead,\n withRetry,\n withTimeout,\n} from \"../resilience/index.js\";\n\n// ============================================================================\n// RPC CLIENT\n// ============================================================================\n\n/**\n * Options for creating an RPC client.\n */\nexport interface RpcClientOptions {\n /** Service name */\n service: string;\n /** RPC transport */\n transport: RpcTransport;\n /** Service configuration */\n config?: ServiceConfig;\n /** Default metadata for all requests */\n defaultMetadata?: RpcMetadata;\n}\n\n/**\n * RPC Client for making service calls\n */\nexport class RpcClient {\n private readonly service: string;\n private readonly transport: RpcTransport;\n private readonly config: Required<ServiceConfig>;\n private readonly defaultMetadata: RpcMetadata;\n private readonly circuitBreaker: CircuitBreaker | null;\n private readonly bulkhead: Bulkhead | null;\n\n constructor(options: RpcClientOptions) {\n this.service = options.service;\n this.transport = options.transport;\n this.config = mergeConfig(options.config);\n this.defaultMetadata = options.defaultMetadata ?? {};\n\n // Initialize circuit breaker\n const cbConfig = this.config.resilience?.circuitBreaker;\n if (\n cbConfig &&\n cbConfig.enabled &&\n cbConfig.failureThreshold !== undefined &&\n cbConfig.resetTimeout !== undefined &&\n cbConfig.successThreshold !== undefined\n ) {\n this.circuitBreaker = new CircuitBreaker({\n failureThreshold: cbConfig.failureThreshold,\n resetTimeout: cbConfig.resetTimeout,\n successThreshold: cbConfig.successThreshold,\n });\n } else {\n this.circuitBreaker = null;\n }\n\n // Initialize bulkhead\n const bhConfig = this.config.resilience?.bulkhead;\n if (bhConfig && bhConfig.maxConcurrent !== undefined && bhConfig.maxQueue !== undefined) {\n this.bulkhead = new Bulkhead({\n maxConcurrent: bhConfig.maxConcurrent,\n maxQueue: bhConfig.maxQueue,\n });\n } else {\n this.bulkhead = null;\n }\n }\n\n /**\n * Execute a query\n */\n async query<TInput, TOutput>(\n method: string,\n input: TInput,\n options?: CallOptions\n ): Promise<TOutput> {\n return this.call<TInput, TOutput>(\"query\", method, input, options);\n }\n\n /**\n * Execute a mutation\n */\n async mutate<TInput, TOutput>(\n method: string,\n input: TInput,\n options?: CallOptions\n ): Promise<TOutput> {\n return this.call<TInput, TOutput>(\"mutation\", method, input, options);\n }\n\n /**\n * Internal call implementation\n */\n private async call<TInput, TOutput>(\n type: \"query\" | \"mutation\",\n method: string,\n input: TInput,\n options?: CallOptions\n ): Promise<TOutput> {\n const request: RpcRequest<TInput> = {\n id: generateId(),\n service: this.service,\n method,\n type,\n input,\n metadata: {\n ...this.defaultMetadata,\n ...options?.metadata,\n },\n };\n\n const version = options?.version ?? this.config.versioning.defaultVersion;\n if (version) {\n request.version = version;\n }\n if (options?.traceContext) {\n request.traceContext = options.traceContext;\n }\n\n const timeout = options?.timeout ?? this.config.resilience.timeout ?? 30_000;\n const retryConfig = options?.retry ?? this.config.resilience.retry;\n\n // Build the execution chain\n let execute = async (): Promise<TOutput> => {\n const response = await this.transport.call<TInput, TOutput>(request);\n\n if (!response.success) {\n const error = toRpcError(\n new Error(response.error?.message ?? \"Unknown error\")\n );\n throw error;\n }\n\n return response.output as TOutput;\n };\n\n // Wrap with timeout\n execute = withTimeout(execute, timeout, () => {\n throw new TimeoutError(this.service, method, timeout);\n });\n\n // Wrap with retry\n const attempts = retryConfig?.attempts ?? 0;\n if (attempts > 0) {\n execute = withRetry(execute, {\n attempts,\n backoff: retryConfig?.backoff ?? \"exponential\",\n initialDelay: retryConfig?.initialDelay ?? 100,\n maxDelay: retryConfig?.maxDelay ?? 5000,\n shouldRetry: (error) => {\n if (error instanceof Error && \"retryable\" in error) {\n return (error as { retryable: boolean }).retryable;\n }\n return false;\n },\n });\n }\n\n // Wrap with circuit breaker\n if (this.circuitBreaker) {\n const cb = this.circuitBreaker;\n const originalExecute = execute;\n execute = async () => {\n return cb.execute(originalExecute);\n };\n }\n\n // Wrap with bulkhead\n if (this.bulkhead) {\n const bh = this.bulkhead;\n const originalExecute = execute;\n execute = async () => {\n return bh.execute(originalExecute);\n };\n }\n\n return execute();\n }\n\n /**\n * Get circuit breaker state\n */\n getCircuitState(): \"closed\" | \"open\" | \"half-open\" | null {\n return this.circuitBreaker?.state ?? null;\n }\n\n /**\n * Get bulkhead stats\n */\n getBulkheadStats(): { concurrent: number; queued: number } | null {\n if (!this.bulkhead) return null;\n return {\n concurrent: this.bulkhead.concurrent,\n queued: this.bulkhead.queued,\n };\n }\n\n /**\n * Close the client and release resources\n */\n async close(): Promise<void> {\n await this.transport.close?.();\n }\n}\n\n/**\n * Options for individual RPC calls.\n * Allows overriding default client settings per-call.\n */\nexport interface CallOptions {\n /** Timeout in ms */\n timeout?: number;\n /** Version requirement */\n version?: string;\n /** Trace context */\n traceContext?: TraceContext;\n /** Request metadata */\n metadata?: RpcMetadata;\n /** Retry configuration override */\n retry?: {\n attempts?: number;\n backoff?: \"linear\" | \"exponential\";\n initialDelay?: number;\n maxDelay?: number;\n };\n}\n\n/**\n * Create an RPC client for making service calls.\n *\n * @param options - Client configuration options\n * @returns A new RPC client instance\n *\n * @example\n * ```typescript\n * const client = createRpcClient({\n * service: 'payments',\n * transport: httpTransport,\n * config: { resilience: { timeout: 5000 } },\n * });\n * const result = await client.query('getSubscription', { id: '123' });\n * ```\n */\nexport function createRpcClient(options: RpcClientOptions): RpcClient {\n return new RpcClient(options);\n}\n","/**\n * @parsrun/service - Configuration\n * Default configuration and config utilities\n */\n\nimport type {\n ServiceConfig,\n EventFormatConfig,\n SerializationConfig,\n TracingConfig,\n VersioningConfig,\n ResilienceConfig,\n DeadLetterConfig,\n} from \"./types.js\";\n\n// ============================================================================\n// DEFAULT CONFIGURATIONS\n// ============================================================================\n\n/**\n * Default event format configuration.\n * Uses CloudEvents format with compact internal communication.\n */\nexport const DEFAULT_EVENT_CONFIG: Required<EventFormatConfig> = {\n format: \"cloudevents\",\n internalCompact: true,\n};\n\n/**\n * Default serialization configuration.\n * Uses JSON format for data encoding.\n */\nexport const DEFAULT_SERIALIZATION_CONFIG: Required<SerializationConfig> = {\n format: \"json\",\n};\n\n/**\n * Default tracing configuration.\n * Enables tracing with 10% sampling ratio and console exporter.\n */\nexport const DEFAULT_TRACING_CONFIG: Required<TracingConfig> = {\n enabled: true,\n sampler: { ratio: 0.1 },\n exporter: \"console\",\n endpoint: \"\",\n serviceName: \"pars-service\",\n};\n\n/**\n * Default versioning configuration.\n * Uses header-based versioning with \"1.x\" as the default version.\n */\nexport const DEFAULT_VERSIONING_CONFIG: Required<VersioningConfig> = {\n strategy: \"header\",\n defaultVersion: \"1.x\",\n};\n\n/**\n * Default resilience configuration.\n * Configures circuit breaker, bulkhead, timeout, and retry settings.\n */\nexport const DEFAULT_RESILIENCE_CONFIG: Required<ResilienceConfig> = {\n circuitBreaker: {\n enabled: true,\n failureThreshold: 5,\n resetTimeout: 30_000,\n successThreshold: 2,\n },\n bulkhead: {\n maxConcurrent: 100,\n maxQueue: 50,\n },\n timeout: 5_000,\n retry: {\n attempts: 3,\n backoff: \"exponential\",\n initialDelay: 100,\n maxDelay: 10_000,\n },\n};\n\n/**\n * Default dead letter queue configuration.\n * Enables DLQ with 30-day retention and alerting at 10 messages.\n */\nexport const DEFAULT_DEAD_LETTER_CONFIG: Required<DeadLetterConfig> = {\n enabled: true,\n retention: \"30d\",\n onFail: \"alert\",\n alertThreshold: 10,\n};\n\n/**\n * Default complete service configuration.\n * Combines all default sub-configurations.\n */\nexport const DEFAULT_SERVICE_CONFIG: Required<ServiceConfig> = {\n events: DEFAULT_EVENT_CONFIG,\n serialization: DEFAULT_SERIALIZATION_CONFIG,\n tracing: DEFAULT_TRACING_CONFIG,\n versioning: DEFAULT_VERSIONING_CONFIG,\n resilience: DEFAULT_RESILIENCE_CONFIG,\n deadLetter: DEFAULT_DEAD_LETTER_CONFIG,\n};\n\n// ============================================================================\n// CONFIG UTILITIES\n// ============================================================================\n\n/**\n * Merge user config with defaults.\n * Deep merges the user configuration with default values.\n *\n * @param userConfig - Optional partial service configuration\n * @returns Complete service configuration with all required fields\n */\nexport function mergeConfig(userConfig?: Partial<ServiceConfig>): Required<ServiceConfig> {\n if (!userConfig) {\n return { ...DEFAULT_SERVICE_CONFIG };\n }\n\n return {\n events: {\n ...DEFAULT_EVENT_CONFIG,\n ...userConfig.events,\n },\n serialization: {\n ...DEFAULT_SERIALIZATION_CONFIG,\n ...userConfig.serialization,\n },\n tracing: {\n ...DEFAULT_TRACING_CONFIG,\n ...userConfig.tracing,\n },\n versioning: {\n ...DEFAULT_VERSIONING_CONFIG,\n ...userConfig.versioning,\n },\n resilience: {\n ...DEFAULT_RESILIENCE_CONFIG,\n ...userConfig.resilience,\n circuitBreaker: {\n ...DEFAULT_RESILIENCE_CONFIG.circuitBreaker,\n ...userConfig.resilience?.circuitBreaker,\n },\n bulkhead: {\n ...DEFAULT_RESILIENCE_CONFIG.bulkhead,\n ...userConfig.resilience?.bulkhead,\n },\n retry: {\n ...DEFAULT_RESILIENCE_CONFIG.retry,\n ...userConfig.resilience?.retry,\n },\n },\n deadLetter: {\n ...DEFAULT_DEAD_LETTER_CONFIG,\n ...userConfig.deadLetter,\n },\n };\n}\n\n/**\n * Create configuration optimized for development.\n * Enables full tracing, disables circuit breaker, and uses longer timeouts.\n *\n * @param overrides - Optional configuration overrides\n * @returns Complete service configuration for development\n */\nexport function createDevConfig(overrides?: Partial<ServiceConfig>): Required<ServiceConfig> {\n return mergeConfig({\n tracing: {\n enabled: true,\n sampler: \"always\",\n exporter: \"console\",\n },\n resilience: {\n circuitBreaker: { enabled: false },\n timeout: 30_000,\n },\n ...overrides,\n });\n}\n\n/**\n * Create configuration optimized for production.\n * Uses 10% sampling ratio, OTLP exporter, and enables circuit breaker.\n *\n * @param overrides - Optional configuration overrides\n * @returns Complete service configuration for production\n */\nexport function createProdConfig(overrides?: Partial<ServiceConfig>): Required<ServiceConfig> {\n return mergeConfig({\n tracing: {\n enabled: true,\n sampler: { ratio: 0.1 },\n exporter: \"otlp\",\n },\n resilience: {\n circuitBreaker: { enabled: true },\n timeout: 5_000,\n },\n ...overrides,\n });\n}\n\n/**\n * Validate service configuration.\n * Checks for valid ranges and values in the configuration.\n *\n * @param config - Service configuration to validate\n * @returns Object containing validation result and any error messages\n */\nexport function validateConfig(config: ServiceConfig): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Validate tracing\n if (config.tracing?.sampler && typeof config.tracing.sampler === \"object\") {\n const ratio = config.tracing.sampler.ratio;\n if (ratio < 0 || ratio > 1) {\n errors.push(\"tracing.sampler.ratio must be between 0 and 1\");\n }\n }\n\n // Validate resilience\n if (config.resilience?.timeout !== undefined && config.resilience.timeout < 0) {\n errors.push(\"resilience.timeout must be non-negative\");\n }\n\n if (config.resilience?.circuitBreaker?.failureThreshold !== undefined) {\n if (config.resilience.circuitBreaker.failureThreshold < 1) {\n errors.push(\"resilience.circuitBreaker.failureThreshold must be at least 1\");\n }\n }\n\n if (config.resilience?.bulkhead?.maxConcurrent !== undefined) {\n if (config.resilience.bulkhead.maxConcurrent < 1) {\n errors.push(\"resilience.bulkhead.maxConcurrent must be at least 1\");\n }\n }\n\n if (config.resilience?.retry?.attempts !== undefined) {\n if (config.resilience.retry.attempts < 0) {\n errors.push(\"resilience.retry.attempts must be non-negative\");\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","/**\n * @parsrun/service - RPC Errors\n */\n\nimport { ParsError } from \"@parsrun/core\";\n\n/**\n * Base RPC error\n */\nexport class RpcError extends ParsError {\n public readonly retryable: boolean;\n public readonly retryAfter?: number;\n\n constructor(\n message: string,\n code: string,\n statusCode: number = 500,\n options?: {\n retryable?: boolean;\n retryAfter?: number;\n details?: Record<string, unknown>;\n }\n ) {\n super(message, code, statusCode, options?.details);\n this.name = \"RpcError\";\n this.retryable = options?.retryable ?? false;\n if (options?.retryAfter !== undefined) {\n this.retryAfter = options.retryAfter;\n }\n }\n}\n\n/**\n * Service not found error\n */\nexport class ServiceNotFoundError extends RpcError {\n constructor(serviceName: string) {\n super(`Service not found: ${serviceName}`, \"SERVICE_NOT_FOUND\", 404, {\n retryable: false,\n details: { service: serviceName },\n });\n this.name = \"ServiceNotFoundError\";\n }\n}\n\n/**\n * Method not found error\n */\nexport class MethodNotFoundError extends RpcError {\n constructor(serviceName: string, methodName: string) {\n super(\n `Method not found: ${serviceName}.${methodName}`,\n \"METHOD_NOT_FOUND\",\n 404,\n {\n retryable: false,\n details: { service: serviceName, method: methodName },\n }\n );\n this.name = \"MethodNotFoundError\";\n }\n}\n\n/**\n * Version mismatch error\n */\nexport class VersionMismatchError extends RpcError {\n constructor(serviceName: string, requested: string, available: string) {\n super(\n `Version mismatch for ${serviceName}: requested ${requested}, available ${available}`,\n \"VERSION_MISMATCH\",\n 400,\n {\n retryable: false,\n details: { service: serviceName, requested, available },\n }\n );\n this.name = \"VersionMismatchError\";\n }\n}\n\n/**\n * Timeout error\n */\nexport class TimeoutError extends RpcError {\n constructor(serviceName: string, methodName: string, timeoutMs: number) {\n super(\n `Request to ${serviceName}.${methodName} timed out after ${timeoutMs}ms`,\n \"TIMEOUT\",\n 504,\n {\n retryable: true,\n details: { service: serviceName, method: methodName, timeout: timeoutMs },\n }\n );\n this.name = \"TimeoutError\";\n }\n}\n\n/**\n * Circuit breaker open error\n */\nexport class CircuitOpenError extends RpcError {\n constructor(serviceName: string, resetAfterMs: number) {\n super(\n `Circuit breaker open for ${serviceName}`,\n \"CIRCUIT_OPEN\",\n 503,\n {\n retryable: true,\n retryAfter: Math.ceil(resetAfterMs / 1000),\n details: { service: serviceName, resetAfterMs },\n }\n );\n this.name = \"CircuitOpenError\";\n }\n}\n\n/**\n * Bulkhead rejected error\n */\nexport class BulkheadRejectedError extends RpcError {\n constructor(serviceName: string) {\n super(\n `Request rejected by bulkhead for ${serviceName}: too many concurrent requests`,\n \"BULKHEAD_REJECTED\",\n 503,\n {\n retryable: true,\n retryAfter: 1,\n details: { service: serviceName },\n }\n );\n this.name = \"BulkheadRejectedError\";\n }\n}\n\n/**\n * Transport error\n */\nexport class TransportError extends RpcError {\n constructor(message: string, cause?: Error) {\n const options: { retryable: boolean; details?: Record<string, unknown> } = {\n retryable: true,\n };\n if (cause) {\n options.details = { cause: cause.message };\n }\n super(message, \"TRANSPORT_ERROR\", 502, options);\n this.name = \"TransportError\";\n }\n}\n\n/**\n * Serialization error\n */\nexport class SerializationError extends RpcError {\n constructor(message: string, cause?: Error) {\n const options: { retryable: boolean; details?: Record<string, unknown> } = {\n retryable: false,\n };\n if (cause) {\n options.details = { cause: cause.message };\n }\n super(message, \"SERIALIZATION_ERROR\", 400, options);\n this.name = \"SerializationError\";\n }\n}\n\n/**\n * Convert unknown error to RpcError\n */\nexport function toRpcError(error: unknown): RpcError {\n if (error instanceof RpcError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new RpcError(error.message, \"INTERNAL_ERROR\", 500, {\n retryable: false,\n details: { originalError: error.name },\n });\n }\n\n return new RpcError(String(error), \"UNKNOWN_ERROR\", 500, {\n retryable: false,\n });\n}\n","/**\n * @parsrun/service - Circuit Breaker\n * Prevents cascading failures by failing fast when a service is unhealthy\n */\n\nimport { CircuitOpenError } from \"../rpc/errors.js\";\n\n// ============================================================================\n// CIRCUIT BREAKER\n// ============================================================================\n\n/**\n * Options for configuring a circuit breaker.\n */\nexport interface CircuitBreakerOptions {\n /** Number of failures before opening circuit */\n failureThreshold: number;\n /** Time to wait before half-open state (ms) */\n resetTimeout: number;\n /** Number of successes in half-open to close circuit */\n successThreshold: number;\n /** Optional callback on state change */\n onStateChange?: (from: CircuitState, to: CircuitState) => void;\n}\n\n/**\n * Circuit breaker state.\n * - \"closed\": Normal operation, requests pass through\n * - \"open\": Failing fast, requests are rejected immediately\n * - \"half-open\": Testing if service recovered, limited requests allowed\n */\nexport type CircuitState = \"closed\" | \"open\" | \"half-open\";\n\n/**\n * Circuit Breaker implementation\n *\n * States:\n * - CLOSED: Normal operation, requests pass through\n * - OPEN: Failing fast, requests are rejected immediately\n * - HALF-OPEN: Testing if service recovered, limited requests allowed\n */\nexport class CircuitBreaker {\n private _state: CircuitState = \"closed\";\n private failures = 0;\n private successes = 0;\n private lastFailureTime = 0;\n private readonly options: CircuitBreakerOptions;\n\n constructor(options: CircuitBreakerOptions) {\n this.options = options;\n }\n\n /**\n * Get current state\n */\n get state(): CircuitState {\n // Check if we should transition from open to half-open\n if (this._state === \"open\") {\n const timeSinceFailure = Date.now() - this.lastFailureTime;\n if (timeSinceFailure >= this.options.resetTimeout) {\n this.transitionTo(\"half-open\");\n }\n }\n return this._state;\n }\n\n /**\n * Execute a function with circuit breaker protection\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n // Check state (this may transition from open to half-open)\n const currentState = this.state;\n\n if (currentState === \"open\") {\n const resetAfter = this.options.resetTimeout - (Date.now() - this.lastFailureTime);\n throw new CircuitOpenError(\"service\", Math.max(0, resetAfter));\n }\n\n try {\n const result = await fn();\n this.onSuccess();\n return result;\n } catch (error) {\n this.onFailure();\n throw error;\n }\n }\n\n /**\n * Record a successful call\n */\n private onSuccess(): void {\n if (this._state === \"half-open\") {\n this.successes++;\n if (this.successes >= this.options.successThreshold) {\n this.transitionTo(\"closed\");\n }\n } else if (this._state === \"closed\") {\n // Reset failure count on success\n this.failures = 0;\n }\n }\n\n /**\n * Record a failed call\n */\n private onFailure(): void {\n this.lastFailureTime = Date.now();\n\n if (this._state === \"half-open\") {\n // Any failure in half-open goes back to open\n this.transitionTo(\"open\");\n } else if (this._state === \"closed\") {\n this.failures++;\n if (this.failures >= this.options.failureThreshold) {\n this.transitionTo(\"open\");\n }\n }\n }\n\n /**\n * Transition to a new state\n */\n private transitionTo(newState: CircuitState): void {\n const oldState = this._state;\n this._state = newState;\n\n // Reset counters on state change\n if (newState === \"closed\") {\n this.failures = 0;\n this.successes = 0;\n } else if (newState === \"half-open\") {\n this.successes = 0;\n }\n\n this.options.onStateChange?.(oldState, newState);\n }\n\n /**\n * Manually reset the circuit breaker\n */\n reset(): void {\n this.transitionTo(\"closed\");\n }\n\n /**\n * Get circuit breaker statistics\n */\n getStats(): {\n state: CircuitState;\n failures: number;\n successes: number;\n lastFailureTime: number;\n } {\n return {\n state: this.state,\n failures: this.failures,\n successes: this.successes,\n lastFailureTime: this.lastFailureTime,\n };\n }\n}\n","/**\n * @parsrun/service - Bulkhead\n * Limits concurrent requests to prevent resource exhaustion\n */\n\nimport { BulkheadRejectedError } from \"../rpc/errors.js\";\n\n// ============================================================================\n// BULKHEAD\n// ============================================================================\n\n/**\n * Options for configuring a bulkhead.\n */\nexport interface BulkheadOptions {\n /** Maximum concurrent requests */\n maxConcurrent: number;\n /** Maximum queue size (0 = no queue) */\n maxQueue: number;\n /** Optional callback when request is rejected */\n onRejected?: () => void;\n}\n\ninterface QueuedRequest<T> {\n fn: () => Promise<T>;\n resolve: (value: T) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * Bulkhead implementation\n *\n * Limits the number of concurrent requests to protect resources.\n * Excess requests can be queued up to maxQueue limit.\n */\nexport class Bulkhead {\n private _concurrent = 0;\n private readonly queue: QueuedRequest<unknown>[] = [];\n private readonly options: BulkheadOptions;\n\n constructor(options: BulkheadOptions) {\n this.options = options;\n }\n\n /**\n * Get current concurrent count\n */\n get concurrent(): number {\n return this._concurrent;\n }\n\n /**\n * Get current queue size\n */\n get queued(): number {\n return this.queue.length;\n }\n\n /**\n * Check if bulkhead is full\n */\n get isFull(): boolean {\n return (\n this._concurrent >= this.options.maxConcurrent &&\n this.queue.length >= this.options.maxQueue\n );\n }\n\n /**\n * Execute a function with bulkhead protection\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n // Check if we can execute immediately\n if (this._concurrent < this.options.maxConcurrent) {\n return this.doExecute(fn);\n }\n\n // Check if we can queue\n if (this.queue.length < this.options.maxQueue) {\n return this.enqueue(fn);\n }\n\n // Reject\n this.options.onRejected?.();\n throw new BulkheadRejectedError(\"service\");\n }\n\n /**\n * Execute immediately\n */\n private async doExecute<T>(fn: () => Promise<T>): Promise<T> {\n this._concurrent++;\n try {\n return await fn();\n } finally {\n this._concurrent--;\n this.processQueue();\n }\n }\n\n /**\n * Add to queue\n */\n private enqueue<T>(fn: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n this.queue.push({\n fn,\n resolve: resolve as (value: unknown) => void,\n reject,\n });\n });\n }\n\n /**\n * Process queued requests\n */\n private processQueue(): void {\n if (this.queue.length === 0) return;\n if (this._concurrent >= this.options.maxConcurrent) return;\n\n const queued = this.queue.shift();\n if (!queued) return;\n\n this.doExecute(queued.fn)\n .then(queued.resolve)\n .catch(queued.reject);\n }\n\n /**\n * Get bulkhead statistics\n */\n getStats(): {\n concurrent: number;\n queued: number;\n maxConcurrent: number;\n maxQueue: number;\n } {\n return {\n concurrent: this._concurrent,\n queued: this.queue.length,\n maxConcurrent: this.options.maxConcurrent,\n maxQueue: this.options.maxQueue,\n };\n }\n\n /**\n * Clear the queue (reject all pending)\n */\n clearQueue(): void {\n const error = new BulkheadRejectedError(\"service\");\n while (this.queue.length > 0) {\n const queued = this.queue.shift();\n queued?.reject(error);\n }\n }\n}\n","/**\n * @parsrun/service - Retry\n * Retry failed operations with backoff\n */\n\n// ============================================================================\n// RETRY\n// ============================================================================\n\n/**\n * Options for configuring retry behavior.\n */\nexport interface RetryOptions {\n /** Number of retry attempts (not including initial attempt) */\n attempts: number;\n /** Backoff strategy */\n backoff: \"linear\" | \"exponential\";\n /** Initial delay in ms */\n initialDelay: number;\n /** Maximum delay in ms */\n maxDelay: number;\n /** Jitter factor (0-1) to add randomness */\n jitter?: number;\n /** Should retry predicate */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n /** Callback on retry */\n onRetry?: (error: unknown, attempt: number, delay: number) => void;\n}\n\n/**\n * Default retry predicate - retry on retryable errors\n */\nconst defaultShouldRetry = (error: unknown): boolean => {\n if (error && typeof error === \"object\" && \"retryable\" in error) {\n return (error as { retryable: boolean }).retryable;\n }\n return false;\n};\n\n/**\n * Calculate delay for retry attempt\n */\nfunction calculateDelay(\n attempt: number,\n options: RetryOptions\n): number {\n let delay: number;\n\n if (options.backoff === \"exponential\") {\n // Exponential backoff: initialDelay * 2^attempt\n delay = options.initialDelay * Math.pow(2, attempt);\n } else {\n // Linear backoff: initialDelay * (attempt + 1)\n delay = options.initialDelay * (attempt + 1);\n }\n\n // Apply max delay\n delay = Math.min(delay, options.maxDelay);\n\n // Apply jitter\n if (options.jitter && options.jitter > 0) {\n const jitterRange = delay * options.jitter;\n delay = delay - jitterRange / 2 + Math.random() * jitterRange;\n }\n\n return Math.round(delay);\n}\n\n/**\n * Sleep for a given duration\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Wrap a function with retry logic.\n * Returns a new function that will retry on failure.\n *\n * @param fn - The function to wrap\n * @param options - Retry configuration\n * @returns A wrapped function with retry behavior\n *\n * @example\n * ```typescript\n * const fetchWithRetry = withRetry(\n * () => fetch('/api/data'),\n * { attempts: 3, backoff: 'exponential', initialDelay: 100, maxDelay: 5000 }\n * );\n * const response = await fetchWithRetry();\n * ```\n */\nexport function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): () => Promise<T> {\n const shouldRetry = options.shouldRetry ?? defaultShouldRetry;\n\n return async (): Promise<T> => {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= options.attempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n // Check if we should retry\n if (attempt >= options.attempts || !shouldRetry(error, attempt)) {\n throw error;\n }\n\n // Calculate delay\n const delay = calculateDelay(attempt, options);\n\n // Callback\n options.onRetry?.(error, attempt + 1, delay);\n\n // Wait before retry\n await sleep(delay);\n }\n }\n\n throw lastError;\n };\n}\n\n/**\n * Execute a function with retry logic immediately.\n *\n * @param fn - The function to execute\n * @param options - Retry configuration\n * @returns Promise resolving to the function result\n */\nexport async function executeWithRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions\n): Promise<T> {\n return withRetry(fn, options)();\n}\n\n/**\n * Create a reusable retry wrapper with preset default options.\n *\n * @param defaultOptions - Default retry configuration\n * @returns A function that executes with retry using the defaults\n *\n * @example\n * ```typescript\n * const retry = createRetryWrapper({ attempts: 3, backoff: 'exponential' });\n * const result = await retry(() => fetchData());\n * ```\n */\nexport function createRetryWrapper(\n defaultOptions: Partial<RetryOptions>\n): <T>(fn: () => Promise<T>, options?: Partial<RetryOptions>) => Promise<T> {\n const defaults: RetryOptions = {\n attempts: defaultOptions.attempts ?? 3,\n backoff: defaultOptions.backoff ?? \"exponential\",\n initialDelay: defaultOptions.initialDelay ?? 100,\n maxDelay: defaultOptions.maxDelay ?? 10_000,\n jitter: defaultOptions.jitter ?? 0.1,\n };\n\n if (defaultOptions.shouldRetry) {\n defaults.shouldRetry = defaultOptions.shouldRetry;\n }\n if (defaultOptions.onRetry) {\n defaults.onRetry = defaultOptions.onRetry;\n }\n\n return async <T>(\n fn: () => Promise<T>,\n options?: Partial<RetryOptions>\n ): Promise<T> => {\n return executeWithRetry(fn, { ...defaults, ...options });\n };\n}\n","/**\n * @parsrun/service - Timeout\n * Timeout wrapper for async operations\n */\n\n// ============================================================================\n// TIMEOUT\n// ============================================================================\n\n/**\n * Error thrown when an operation exceeds its timeout.\n */\nexport class TimeoutExceededError extends Error {\n /** The timeout value in milliseconds that was exceeded */\n readonly timeout: number;\n\n constructor(timeout: number) {\n super(`Operation timed out after ${timeout}ms`);\n this.name = \"TimeoutExceededError\";\n this.timeout = timeout;\n }\n}\n\n/**\n * Wrap a function with a timeout.\n * Returns a new function that will reject if the timeout is exceeded.\n *\n * @param fn - The function to wrap\n * @param timeoutMs - Timeout in milliseconds\n * @param onTimeout - Optional callback or throw function when timeout occurs\n * @returns A wrapped function with timeout behavior\n */\nexport function withTimeout<T>(\n fn: () => Promise<T>,\n timeoutMs: number,\n onTimeout?: () => void | never\n): () => Promise<T> {\n return async (): Promise<T> => {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n if (onTimeout) {\n try {\n onTimeout();\n } catch (error) {\n reject(error);\n return;\n }\n }\n reject(new TimeoutExceededError(timeoutMs));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([fn(), timeoutPromise]);\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n };\n}\n\n/**\n * Execute a function with timeout immediately.\n *\n * @param fn - The function to execute\n * @param timeoutMs - Timeout in milliseconds\n * @param onTimeout - Optional callback or throw function when timeout occurs\n * @returns Promise resolving to the function result or rejecting on timeout\n */\nexport async function executeWithTimeout<T>(\n fn: () => Promise<T>,\n timeoutMs: number,\n onTimeout?: () => void | never\n): Promise<T> {\n return withTimeout(fn, timeoutMs, onTimeout)();\n}\n\n/**\n * Create a reusable timeout wrapper with preset duration.\n *\n * @param defaultTimeoutMs - Default timeout in milliseconds\n * @returns A function that executes with timeout\n */\nexport function createTimeoutWrapper(\n defaultTimeoutMs: number\n): <T>(fn: () => Promise<T>, timeoutMs?: number) => Promise<T> {\n return async <T>(fn: () => Promise<T>, timeoutMs?: number): Promise<T> => {\n return executeWithTimeout(fn, timeoutMs ?? defaultTimeoutMs);\n };\n}\n\n/**\n * Race multiple promises with a timeout.\n * Returns the first promise to resolve, or rejects on timeout.\n *\n * @param promises - Array of promises to race\n * @param timeoutMs - Timeout in milliseconds\n * @returns Promise resolving to the first result\n */\nexport async function raceWithTimeout<T>(\n promises: Promise<T>[],\n timeoutMs: number\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new TimeoutExceededError(timeoutMs));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([...promises, timeoutPromise]);\n } finally {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n }\n}\n\n/**\n * Execute a function with an absolute deadline.\n * Converts the deadline to a relative timeout.\n *\n * @param fn - The function to execute\n * @param deadline - Absolute deadline as a Date\n * @returns Promise resolving to the function result\n */\nexport async function executeWithDeadline<T>(\n fn: () => Promise<T>,\n deadline: Date\n): Promise<T> {\n const now = Date.now();\n const deadlineMs = deadline.getTime();\n const timeoutMs = Math.max(0, deadlineMs - now);\n\n if (timeoutMs === 0) {\n throw new TimeoutExceededError(0);\n }\n\n return executeWithTimeout(fn, timeoutMs);\n}\n","/**\n * @parsrun/service - RPC Server\n * Server for handling RPC requests\n */\n\nimport type { Logger } from \"@parsrun/core\";\nimport { createLogger } from \"@parsrun/core\";\nimport type {\n RpcRequest,\n RpcResponse,\n ServiceDefinition,\n TraceContext,\n} from \"../types.js\";\nimport { satisfiesVersion, isMethodDeprecated, getMethodTimeout } from \"../define.js\";\nimport { MethodNotFoundError, VersionMismatchError, toRpcError } from \"./errors.js\";\n\n// ============================================================================\n// RPC HANDLER TYPES\n// ============================================================================\n\n/**\n * RPC handler context\n */\nexport interface RpcHandlerContext {\n /** Request ID */\n requestId: string;\n /** Service name */\n service: string;\n /** Method name */\n method: string;\n /** Method type */\n type: \"query\" | \"mutation\";\n /** Request metadata */\n metadata: Record<string, unknown>;\n /** Trace context */\n traceContext?: TraceContext;\n /** Logger */\n logger: Logger;\n}\n\n/**\n * RPC handler function\n */\nexport type RpcHandler<TInput = unknown, TOutput = unknown> = (\n input: TInput,\n context: RpcHandlerContext\n) => Promise<TOutput>;\n\n/**\n * RPC handlers record\n */\nexport type RpcHandlers = {\n queries?: Record<string, RpcHandler>;\n mutations?: Record<string, RpcHandler>;\n};\n\n// ============================================================================\n// RPC SERVER\n// ============================================================================\n\n/**\n * Options for creating an RPC server.\n */\nexport interface RpcServerOptions {\n /** Service definition */\n definition: ServiceDefinition;\n /** RPC handlers */\n handlers: RpcHandlers;\n /** Logger */\n logger?: Logger;\n /** Default timeout in ms */\n defaultTimeout?: number;\n /** Middleware */\n middleware?: RpcMiddleware[];\n}\n\n/**\n * RPC middleware function for request processing.\n * Middleware can intercept, modify, or handle requests before/after handlers.\n *\n * @param request - The incoming RPC request\n * @param context - Handler context with logger and metadata\n * @param next - Function to call the next middleware or handler\n * @returns Promise resolving to the handler result\n */\nexport type RpcMiddleware = (\n request: RpcRequest,\n context: RpcHandlerContext,\n next: () => Promise<unknown>\n) => Promise<unknown>;\n\n/**\n * RPC Server for handling incoming requests\n */\nexport class RpcServer {\n private readonly definition: ServiceDefinition;\n private readonly handlers: RpcHandlers;\n private readonly logger: Logger;\n private readonly defaultTimeout: number;\n private readonly middleware: RpcMiddleware[];\n\n constructor(options: RpcServerOptions) {\n this.definition = options.definition;\n this.handlers = options.handlers;\n this.logger = options.logger ?? createLogger({ name: `rpc:${options.definition.name}` });\n this.defaultTimeout = options.defaultTimeout ?? 30_000;\n this.middleware = options.middleware ?? [];\n }\n\n /**\n * Handle an RPC request\n */\n async handle<TInput, TOutput>(request: RpcRequest<TInput>): Promise<RpcResponse<TOutput>> {\n const startTime = Date.now();\n const context: RpcHandlerContext = {\n requestId: request.id,\n service: request.service,\n method: request.method,\n type: request.type,\n metadata: request.metadata ?? {},\n logger: this.logger.child({ requestId: request.id, method: request.method }),\n };\n\n if (request.traceContext) {\n context.traceContext = request.traceContext;\n }\n\n try {\n // Check version compatibility\n if (request.version && !satisfiesVersion(this.definition.version, request.version)) {\n throw new VersionMismatchError(\n this.definition.name,\n request.version,\n this.definition.version\n );\n }\n\n // Get handler\n const handler = this.getHandler(request.method, request.type);\n if (!handler) {\n throw new MethodNotFoundError(this.definition.name, request.method);\n }\n\n // Check deprecation\n const deprecation = isMethodDeprecated(this.definition, request.method, request.type);\n if (deprecation.deprecated) {\n context.logger.warn(`Method ${request.method} is deprecated`, {\n since: deprecation.since,\n replacement: deprecation.replacement,\n });\n }\n\n // Build middleware chain\n const chain = this.buildMiddlewareChain(request, context, handler);\n\n // Execute with timeout\n const timeout = getMethodTimeout(\n this.definition,\n request.method,\n request.type,\n this.defaultTimeout\n );\n\n const output = await Promise.race([\n chain(),\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error(\"Handler timeout\")), timeout)\n ),\n ]);\n\n const duration = Date.now() - startTime;\n context.logger.info(`${request.type} ${request.method} completed`, { durationMs: duration });\n\n const successResponse: RpcResponse<TOutput> = {\n id: request.id,\n success: true,\n version: this.definition.version,\n output: output as TOutput,\n };\n if (request.traceContext) {\n successResponse.traceContext = request.traceContext;\n }\n return successResponse;\n } catch (error) {\n const duration = Date.now() - startTime;\n const rpcError = toRpcError(error);\n\n context.logger.error(`${request.type} ${request.method} failed`, error as Error, {\n durationMs: duration,\n errorCode: rpcError.code,\n });\n\n const errorData: RpcResponse<TOutput>[\"error\"] = {\n code: rpcError.code,\n message: rpcError.message,\n retryable: rpcError.retryable,\n };\n if (rpcError.details) {\n errorData!.details = rpcError.details;\n }\n if (rpcError.retryAfter !== undefined) {\n errorData!.retryAfter = rpcError.retryAfter;\n }\n\n const errorResponse: RpcResponse<TOutput> = {\n id: request.id,\n success: false,\n version: this.definition.version,\n error: errorData,\n };\n if (request.traceContext) {\n errorResponse.traceContext = request.traceContext;\n }\n return errorResponse;\n }\n }\n\n /**\n * Get handler for a method\n */\n private getHandler(method: string, type: \"query\" | \"mutation\"): RpcHandler | undefined {\n const handlers = type === \"query\" ? this.handlers.queries : this.handlers.mutations;\n return handlers?.[method];\n }\n\n /**\n * Build middleware chain\n */\n private buildMiddlewareChain(\n request: RpcRequest,\n context: RpcHandlerContext,\n handler: RpcHandler\n ): () => Promise<unknown> {\n let index = -1;\n\n const dispatch = async (i: number): Promise<unknown> => {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n\n if (i < this.middleware.length) {\n const mw = this.middleware[i]!;\n return mw(request, context, () => dispatch(i + 1));\n }\n\n return handler(request.input, context);\n };\n\n return () => dispatch(0);\n }\n\n /**\n * Get service definition\n */\n getDefinition(): ServiceDefinition {\n return this.definition;\n }\n\n /**\n * Get registered methods\n */\n getMethods(): { queries: string[]; mutations: string[] } {\n return {\n queries: Object.keys(this.handlers.queries ?? {}),\n mutations: Object.keys(this.handlers.mutations ?? {}),\n };\n }\n}\n\n/**\n * Create an RPC server for handling incoming requests.\n *\n * @param options - Server configuration options\n * @returns A new RPC server instance\n *\n * @example\n * ```typescript\n * const server = createRpcServer({\n * definition: paymentsService,\n * handlers: {\n * queries: {\n * getSubscription: async (input, ctx) => {\n * return { status: 'active', plan: 'pro' };\n * },\n * },\n * },\n * middleware: [loggingMiddleware()],\n * });\n * ```\n */\nexport function createRpcServer(options: RpcServerOptions): RpcServer {\n return new RpcServer(options);\n}\n\n// ============================================================================\n// BUILT-IN MIDDLEWARE\n// ============================================================================\n\n/**\n * Create logging middleware for RPC requests.\n * Logs request start and completion with input keys.\n *\n * @returns RPC middleware that logs requests\n */\nexport function loggingMiddleware(): RpcMiddleware {\n return async (request, context, next) => {\n context.logger.debug(`Handling ${request.type} ${request.method}`, {\n inputKeys: Object.keys(request.input as object),\n });\n\n const result = await next();\n\n context.logger.debug(`Completed ${request.type} ${request.method}`);\n\n return result;\n };\n}\n\n/**\n * Create validation middleware for RPC request inputs.\n * Applies validators to request inputs by method name.\n *\n * @param validators - Map of method names to validation functions\n * @returns RPC middleware that validates inputs\n *\n * @example\n * ```typescript\n * const middleware = validationMiddleware({\n * createUser: (input) => validateUserInput(input),\n * });\n * ```\n */\nexport function validationMiddleware(\n validators: Record<string, (input: unknown) => unknown>\n): RpcMiddleware {\n return async (request, _context, next) => {\n const validator = validators[request.method];\n if (validator) {\n request.input = validator(request.input);\n }\n return next();\n };\n}\n\n/**\n * Create tenant context middleware.\n * Extracts tenant ID from request metadata and adds it to the logger context.\n *\n * @returns RPC middleware that enriches logger with tenant context\n */\nexport function tenantMiddleware(): RpcMiddleware {\n return async (_request, context, next) => {\n const tenantId = context.metadata[\"tenantId\"];\n if (tenantId) {\n context.logger = context.logger.child({ tenantId });\n }\n return next();\n };\n}\n","/**\n * @parsrun/service - Service Definition\n * Factory function for defining services\n */\n\nimport type {\n ServiceDefinition,\n QueryDefinition,\n MutationDefinition,\n EventDefinition,\n} from \"./types.js\";\n\n// ============================================================================\n// SERVICE DEFINITION FACTORY\n// ============================================================================\n\n/**\n * Define a service with type-safe queries, mutations, and events\n *\n * @example\n * ```typescript\n * const paymentsService = defineService({\n * name: 'payments',\n * version: '1.0.0',\n *\n * queries: {\n * getSubscription: {\n * input: { subscriptionId: 'string' },\n * output: { status: 'string', plan: 'string' },\n * },\n * },\n *\n * mutations: {\n * subscribe: {\n * input: { email: 'string', planId: 'string' },\n * output: { checkoutUrl: 'string' },\n * },\n * },\n *\n * events: {\n * emits: {\n * 'subscription.created': {\n * data: { customerId: 'string', planId: 'string' },\n * delivery: 'at-least-once',\n * },\n * },\n * handles: ['user.deleted', 'tenant.suspended'],\n * },\n * });\n * ```\n */\nexport function defineService<\n TQueries extends Record<string, QueryDefinition> = Record<string, QueryDefinition>,\n TMutations extends Record<string, MutationDefinition> = Record<string, MutationDefinition>,\n TEmits extends Record<string, EventDefinition> = Record<string, EventDefinition>,\n THandles extends string[] = string[],\n>(\n definition: ServiceDefinition<TQueries, TMutations, TEmits, THandles>\n): ServiceDefinition<TQueries, TMutations, TEmits, THandles> {\n // Validate service definition\n validateServiceDefinition(definition);\n\n // Freeze the definition to prevent mutation\n return Object.freeze({\n ...definition,\n queries: definition.queries ? Object.freeze({ ...definition.queries }) : undefined,\n mutations: definition.mutations ? Object.freeze({ ...definition.mutations }) : undefined,\n events: definition.events\n ? Object.freeze({\n emits: definition.events.emits\n ? Object.freeze({ ...definition.events.emits })\n : undefined,\n handles: definition.events.handles\n ? Object.freeze([...definition.events.handles])\n : undefined,\n })\n : undefined,\n }) as ServiceDefinition<TQueries, TMutations, TEmits, THandles>;\n}\n\n/**\n * Validate service definition\n */\nfunction validateServiceDefinition(definition: ServiceDefinition): void {\n if (!definition.name) {\n throw new Error(\"Service name is required\");\n }\n\n if (!definition.version) {\n throw new Error(\"Service version is required\");\n }\n\n // Validate version format (semver-like)\n const versionRegex = /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?$/;\n if (!versionRegex.test(definition.version)) {\n throw new Error(`Invalid version format: ${definition.version}. Expected semver (e.g., 1.0.0)`);\n }\n\n // Validate query/mutation names (no dots or special chars)\n const nameRegex = /^[a-zA-Z][a-zA-Z0-9_]*$/;\n\n if (definition.queries) {\n for (const name of Object.keys(definition.queries)) {\n if (!nameRegex.test(name)) {\n throw new Error(\n `Invalid query name: ${name}. Must start with letter and contain only alphanumeric and underscore`\n );\n }\n }\n }\n\n if (definition.mutations) {\n for (const name of Object.keys(definition.mutations)) {\n if (!nameRegex.test(name)) {\n throw new Error(\n `Invalid mutation name: ${name}. Must start with letter and contain only alphanumeric and underscore`\n );\n }\n }\n }\n\n // Validate event names (dot notation allowed)\n const eventNameRegex = /^[a-zA-Z][a-zA-Z0-9_.]*$/;\n\n if (definition.events?.emits) {\n for (const name of Object.keys(definition.events.emits)) {\n if (!eventNameRegex.test(name)) {\n throw new Error(\n `Invalid event name: ${name}. Must start with letter and contain only alphanumeric, underscore, and dot`\n );\n }\n }\n }\n\n if (definition.events?.handles) {\n for (const name of definition.events.handles) {\n if (!eventNameRegex.test(name)) {\n throw new Error(\n `Invalid handled event name: ${name}. Must start with letter and contain only alphanumeric, underscore, and dot`\n );\n }\n }\n }\n}\n\n// ============================================================================\n// SERVICE DEFINITION UTILITIES\n// ============================================================================\n\n/**\n * Get all method names from a service definition.\n *\n * @param definition - The service definition\n * @returns Object containing arrays of query and mutation names\n */\nexport function getServiceMethods(definition: ServiceDefinition): {\n queries: string[];\n mutations: string[];\n} {\n return {\n queries: definition.queries ? Object.keys(definition.queries) : [],\n mutations: definition.mutations ? Object.keys(definition.mutations) : [],\n };\n}\n\n/**\n * Get all event types from a service definition.\n *\n * @param definition - The service definition\n * @returns Object containing arrays of emitted and handled event types\n */\nexport function getServiceEvents(definition: ServiceDefinition): {\n emits: string[];\n handles: string[];\n} {\n return {\n emits: definition.events?.emits ? Object.keys(definition.events.emits) : [],\n handles: definition.events?.handles ?? [],\n };\n}\n\n/**\n * Check if a service version satisfies a version requirement.\n * Supports wildcards (x or *) in version requirements.\n *\n * @param version - The actual version to check\n * @param requirement - The version requirement with optional wildcards\n * @returns True if the version satisfies the requirement\n *\n * @example\n * ```typescript\n * satisfiesVersion('1.2.3', '1.x') // true\n * satisfiesVersion('1.2.3', '1.2.x') // true\n * satisfiesVersion('2.0.0', '1.x') // false\n * ```\n */\nexport function satisfiesVersion(version: string, requirement: string): boolean {\n const versionParts = version.split(\".\").map((p) => parseInt(p, 10));\n const requirementParts = requirement.split(\".\");\n\n for (let i = 0; i < requirementParts.length; i++) {\n const req = requirementParts[i];\n if (req === \"x\" || req === \"*\") {\n continue;\n }\n\n const reqNum = parseInt(req ?? \"0\", 10);\n const verNum = versionParts[i] ?? 0;\n\n if (verNum !== reqNum) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Check if a method is deprecated in the service definition.\n *\n * @param definition - The service definition\n * @param methodName - Name of the method to check\n * @param type - Type of method (\"query\" or \"mutation\")\n * @returns Object with deprecation status and optional metadata\n */\nexport function isMethodDeprecated(\n definition: ServiceDefinition,\n methodName: string,\n type: \"query\" | \"mutation\"\n): { deprecated: boolean; since?: string; replacement?: string } {\n const methods = type === \"query\" ? definition.queries : definition.mutations;\n const method = methods?.[methodName];\n\n if (!method?.deprecated) {\n return { deprecated: false };\n }\n\n const result: { deprecated: boolean; since?: string; replacement?: string } = {\n deprecated: true,\n since: method.deprecated,\n };\n\n if (method.replacement) {\n result.replacement = method.replacement;\n }\n\n return result;\n}\n\n/**\n * Get method timeout from the service definition.\n * Uses method-specific timeout if defined, otherwise falls back to default.\n *\n * @param definition - The service definition\n * @param methodName - Name of the method\n * @param type - Type of method (\"query\" or \"mutation\")\n * @param defaultTimeout - Default timeout to use if not specified\n * @returns Timeout value in milliseconds\n */\nexport function getMethodTimeout(\n definition: ServiceDefinition,\n methodName: string,\n type: \"query\" | \"mutation\",\n defaultTimeout: number\n): number {\n const methods = type === \"query\" ? definition.queries : definition.mutations;\n const method = methods?.[methodName];\n\n return method?.timeout ?? defaultTimeout;\n}\n","/**\n * @parsrun/service - Embedded RPC Transport\n * Direct function call transport for monolithic/embedded mode\n */\n\nimport type { RpcRequest, RpcResponse, RpcTransport } from \"../../types.js\";\nimport type { RpcServer } from \"../server.js\";\n\n// ============================================================================\n// EMBEDDED TRANSPORT\n// ============================================================================\n\n/**\n * Embedded transport that calls handlers directly\n * Used when services are in the same process\n */\nexport class EmbeddedTransport implements RpcTransport {\n readonly name = \"embedded\";\n private readonly server: RpcServer;\n\n constructor(server: RpcServer) {\n this.server = server;\n }\n\n async call<TInput, TOutput>(request: RpcRequest<TInput>): Promise<RpcResponse<TOutput>> {\n // Direct call to server - no serialization needed\n return this.server.handle<TInput, TOutput>(request);\n }\n\n async close(): Promise<void> {\n // No cleanup needed for embedded transport\n }\n}\n\n/**\n * Create an embedded transport for direct function calls.\n * Used when the service is in the same process.\n *\n * @param server - The RPC server to call directly\n * @returns A new embedded transport instance\n *\n * @example\n * ```typescript\n * const transport = createEmbeddedTransport(rpcServer);\n * const client = createRpcClient({ service: 'payments', transport });\n * ```\n */\nexport function createEmbeddedTransport(server: RpcServer): EmbeddedTransport {\n return new EmbeddedTransport(server);\n}\n\n// ============================================================================\n// EMBEDDED TRANSPORT REGISTRY\n// ============================================================================\n\n/**\n * Registry for embedded services\n * Allows services to find each other in embedded mode\n */\nexport class EmbeddedRegistry {\n private static instance: EmbeddedRegistry | null = null;\n private readonly servers: Map<string, RpcServer> = new Map();\n\n private constructor() {}\n\n static getInstance(): EmbeddedRegistry {\n if (!EmbeddedRegistry.instance) {\n EmbeddedRegistry.instance = new EmbeddedRegistry();\n }\n return EmbeddedRegistry.instance;\n }\n\n /**\n * Register a service\n */\n register(name: string, server: RpcServer): void {\n if (this.servers.has(name)) {\n throw new Error(`Service already registered: ${name}`);\n }\n this.servers.set(name, server);\n }\n\n /**\n * Unregister a service\n */\n unregister(name: string): boolean {\n return this.servers.delete(name);\n }\n\n /**\n * Get a service by name\n */\n get(name: string): RpcServer | undefined {\n return this.servers.get(name);\n }\n\n /**\n * Check if a service is registered\n */\n has(name: string): boolean {\n return this.servers.has(name);\n }\n\n /**\n * Get all registered service names\n */\n getServiceNames(): string[] {\n return Array.from(this.servers.keys());\n }\n\n /**\n * Create a transport for a registered service\n */\n createTransport(name: string): EmbeddedTransport {\n const server = this.servers.get(name);\n if (!server) {\n throw new Error(`Service not found: ${name}`);\n }\n return new EmbeddedTransport(server);\n }\n\n /**\n * Clear all registered services\n */\n clear(): void {\n this.servers.clear();\n }\n\n /**\n * Reset the singleton instance (for testing)\n */\n static reset(): void {\n EmbeddedRegistry.instance = null;\n }\n}\n\n/**\n * Get the global embedded registry singleton.\n * Provides access to the shared registry for service discovery.\n *\n * @returns The global embedded registry instance\n *\n * @example\n * ```typescript\n * const registry = getEmbeddedRegistry();\n * registry.register('payments', paymentsServer);\n * const transport = registry.createTransport('payments');\n * ```\n */\nexport function getEmbeddedRegistry(): EmbeddedRegistry {\n return EmbeddedRegistry.getInstance();\n}\n","/**\n * @parsrun/service - Serialization\n * JSON and MessagePack serializers\n */\n\n// ============================================================================\n// SERIALIZER INTERFACE\n// ============================================================================\n\n/**\n * Serializer interface for encoding/decoding data\n */\nexport interface Serializer {\n /** Encode data to string or buffer */\n encode(data: unknown): string | ArrayBuffer;\n /** Decode string or buffer to data */\n decode(raw: string | ArrayBuffer): unknown;\n /** Content type for HTTP headers */\n contentType: string;\n}\n\n// ============================================================================\n// JSON SERIALIZER\n// ============================================================================\n\n/**\n * JSON serializer (default)\n */\nexport const jsonSerializer: Serializer = {\n encode(data: unknown): string {\n return JSON.stringify(data);\n },\n\n decode(raw: string | ArrayBuffer): unknown {\n if (raw instanceof ArrayBuffer) {\n const decoder = new TextDecoder();\n return JSON.parse(decoder.decode(raw));\n }\n return JSON.parse(raw);\n },\n\n contentType: \"application/json\",\n};\n\n// ============================================================================\n// MESSAGEPACK SERIALIZER (Lightweight implementation)\n// ============================================================================\n\n/**\n * Lightweight MessagePack encoder\n * Supports: null, boolean, number, string, array, object\n */\nfunction msgpackEncode(value: unknown): Uint8Array {\n const parts: Uint8Array[] = [];\n\n function encode(val: unknown): void {\n if (val === null || val === undefined) {\n parts.push(new Uint8Array([0xc0])); // nil\n return;\n }\n\n if (typeof val === \"boolean\") {\n parts.push(new Uint8Array([val ? 0xc3 : 0xc2]));\n return;\n }\n\n if (typeof val === \"number\") {\n if (Number.isInteger(val)) {\n if (val >= 0 && val <= 127) {\n // positive fixint\n parts.push(new Uint8Array([val]));\n } else if (val < 0 && val >= -32) {\n // negative fixint\n parts.push(new Uint8Array([val & 0xff]));\n } else if (val >= 0 && val <= 0xff) {\n // uint8\n parts.push(new Uint8Array([0xcc, val]));\n } else if (val >= 0 && val <= 0xffff) {\n // uint16\n parts.push(new Uint8Array([0xcd, (val >> 8) & 0xff, val & 0xff]));\n } else if (val >= 0 && val <= 0xffffffff) {\n // uint32\n parts.push(\n new Uint8Array([\n 0xce,\n (val >> 24) & 0xff,\n (val >> 16) & 0xff,\n (val >> 8) & 0xff,\n val & 0xff,\n ])\n );\n } else if (val >= -128 && val <= 127) {\n // int8\n parts.push(new Uint8Array([0xd0, val & 0xff]));\n } else if (val >= -32768 && val <= 32767) {\n // int16\n parts.push(new Uint8Array([0xd1, (val >> 8) & 0xff, val & 0xff]));\n } else if (val >= -2147483648 && val <= 2147483647) {\n // int32\n parts.push(\n new Uint8Array([\n 0xd2,\n (val >> 24) & 0xff,\n (val >> 16) & 0xff,\n (val >> 8) & 0xff,\n val & 0xff,\n ])\n );\n } else {\n // Fall back to float64 for large integers\n const buffer = new ArrayBuffer(9);\n const view = new DataView(buffer);\n view.setUint8(0, 0xcb);\n view.setFloat64(1, val, false);\n parts.push(new Uint8Array(buffer));\n }\n } else {\n // float64\n const buffer = new ArrayBuffer(9);\n const view = new DataView(buffer);\n view.setUint8(0, 0xcb);\n view.setFloat64(1, val, false);\n parts.push(new Uint8Array(buffer));\n }\n return;\n }\n\n if (typeof val === \"string\") {\n const encoded = new TextEncoder().encode(val);\n const len = encoded.length;\n\n if (len <= 31) {\n // fixstr\n parts.push(new Uint8Array([0xa0 | len]));\n } else if (len <= 0xff) {\n // str8\n parts.push(new Uint8Array([0xd9, len]));\n } else if (len <= 0xffff) {\n // str16\n parts.push(new Uint8Array([0xda, (len >> 8) & 0xff, len & 0xff]));\n } else {\n // str32\n parts.push(\n new Uint8Array([\n 0xdb,\n (len >> 24) & 0xff,\n (len >> 16) & 0xff,\n (len >> 8) & 0xff,\n len & 0xff,\n ])\n );\n }\n parts.push(encoded);\n return;\n }\n\n if (Array.isArray(val)) {\n const len = val.length;\n\n if (len <= 15) {\n // fixarray\n parts.push(new Uint8Array([0x90 | len]));\n } else if (len <= 0xffff) {\n // array16\n parts.push(new Uint8Array([0xdc, (len >> 8) & 0xff, len & 0xff]));\n } else {\n // array32\n parts.push(\n new Uint8Array([\n 0xdd,\n (len >> 24) & 0xff,\n (len >> 16) & 0xff,\n (len >> 8) & 0xff,\n len & 0xff,\n ])\n );\n }\n\n for (const item of val) {\n encode(item);\n }\n return;\n }\n\n if (typeof val === \"object\") {\n const keys = Object.keys(val as object);\n const len = keys.length;\n\n if (len <= 15) {\n // fixmap\n parts.push(new Uint8Array([0x80 | len]));\n } else if (len <= 0xffff) {\n // map16\n parts.push(new Uint8Array([0xde, (len >> 8) & 0xff, len & 0xff]));\n } else {\n // map32\n parts.push(\n new Uint8Array([\n 0xdf,\n (len >> 24) & 0xff,\n (len >> 16) & 0xff,\n (len >> 8) & 0xff,\n len & 0xff,\n ])\n );\n }\n\n for (const key of keys) {\n encode(key);\n encode((val as Record<string, unknown>)[key]);\n }\n return;\n }\n\n // Unsupported type - encode as null\n parts.push(new Uint8Array([0xc0]));\n }\n\n encode(value);\n\n // Merge all parts\n const totalLength = parts.reduce((sum, p) => sum + p.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const part of parts) {\n result.set(part, offset);\n offset += part.length;\n }\n\n return result;\n}\n\n/**\n * Lightweight MessagePack decoder\n */\nfunction msgpackDecode(buffer: Uint8Array): unknown {\n let offset = 0;\n\n function decode(): unknown {\n if (offset >= buffer.length) {\n throw new Error(\"Unexpected end of buffer\");\n }\n\n const byte = buffer[offset++]!;\n\n // Positive fixint (0x00 - 0x7f)\n if (byte <= 0x7f) {\n return byte;\n }\n\n // Negative fixint (0xe0 - 0xff)\n if (byte >= 0xe0) {\n return byte - 256;\n }\n\n // Fixmap (0x80 - 0x8f)\n if (byte >= 0x80 && byte <= 0x8f) {\n const len = byte - 0x80;\n const result: Record<string, unknown> = {};\n for (let i = 0; i < len; i++) {\n const key = decode() as string;\n result[key] = decode();\n }\n return result;\n }\n\n // Fixarray (0x90 - 0x9f)\n if (byte >= 0x90 && byte <= 0x9f) {\n const len = byte - 0x90;\n const result: unknown[] = [];\n for (let i = 0; i < len; i++) {\n result.push(decode());\n }\n return result;\n }\n\n // Fixstr (0xa0 - 0xbf)\n if (byte >= 0xa0 && byte <= 0xbf) {\n const len = byte - 0xa0;\n const str = new TextDecoder().decode(buffer.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n\n switch (byte) {\n case 0xc0: // nil\n return null;\n case 0xc2: // false\n return false;\n case 0xc3: // true\n return true;\n\n case 0xcc: // uint8\n return buffer[offset++];\n case 0xcd: // uint16\n return (buffer[offset++]! << 8) | buffer[offset++]!;\n case 0xce: // uint32\n return (\n ((buffer[offset++]! << 24) >>> 0) +\n (buffer[offset++]! << 16) +\n (buffer[offset++]! << 8) +\n buffer[offset++]!\n );\n\n case 0xd0: // int8\n {\n const val = buffer[offset++]!;\n return val > 127 ? val - 256 : val;\n }\n case 0xd1: // int16\n {\n const val = (buffer[offset++]! << 8) | buffer[offset++]!;\n return val > 32767 ? val - 65536 : val;\n }\n case 0xd2: // int32\n {\n const val =\n (buffer[offset++]! << 24) |\n (buffer[offset++]! << 16) |\n (buffer[offset++]! << 8) |\n buffer[offset++]!;\n return val;\n }\n\n case 0xcb: // float64\n {\n const view = new DataView(buffer.buffer, buffer.byteOffset + offset, 8);\n offset += 8;\n return view.getFloat64(0, false);\n }\n\n case 0xd9: // str8\n {\n const len = buffer[offset++]!;\n const str = new TextDecoder().decode(buffer.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n case 0xda: // str16\n {\n const len = (buffer[offset++]! << 8) | buffer[offset++]!;\n const str = new TextDecoder().decode(buffer.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n case 0xdb: // str32\n {\n const len =\n (buffer[offset++]! << 24) |\n (buffer[offset++]! << 16) |\n (buffer[offset++]! << 8) |\n buffer[offset++]!;\n const str = new TextDecoder().decode(buffer.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n\n case 0xdc: // array16\n {\n const len = (buffer[offset++]! << 8) | buffer[offset++]!;\n const result: unknown[] = [];\n for (let i = 0; i < len; i++) {\n result.push(decode());\n }\n return result;\n }\n case 0xdd: // array32\n {\n const len =\n (buffer[offset++]! << 24) |\n (buffer[offset++]! << 16) |\n (buffer[offset++]! << 8) |\n buffer[offset++]!;\n const result: unknown[] = [];\n for (let i = 0; i < len; i++) {\n result.push(decode());\n }\n return result;\n }\n\n case 0xde: // map16\n {\n const len = (buffer[offset++]! << 8) | buffer[offset++]!;\n const result: Record<string, unknown> = {};\n for (let i = 0; i < len; i++) {\n const key = decode() as string;\n result[key] = decode();\n }\n return result;\n }\n case 0xdf: // map32\n {\n const len =\n (buffer[offset++]! << 24) |\n (buffer[offset++]! << 16) |\n (buffer[offset++]! << 8) |\n buffer[offset++]!;\n const result: Record<string, unknown> = {};\n for (let i = 0; i < len; i++) {\n const key = decode() as string;\n result[key] = decode();\n }\n return result;\n }\n\n default:\n throw new Error(`Unknown MessagePack type: 0x${byte.toString(16)}`);\n }\n }\n\n return decode();\n}\n\n/**\n * MessagePack serializer\n */\nexport const msgpackSerializer: Serializer = {\n encode(data: unknown): ArrayBuffer {\n const encoded = msgpackEncode(data);\n // Create a new ArrayBuffer with the exact bytes from the Uint8Array\n const buffer = new ArrayBuffer(encoded.byteLength);\n new Uint8Array(buffer).set(encoded);\n return buffer;\n },\n\n decode(raw: string | ArrayBuffer): unknown {\n if (typeof raw === \"string\") {\n // If string is passed, assume it's base64 encoded\n const binary = atob(raw);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return msgpackDecode(bytes);\n }\n return msgpackDecode(new Uint8Array(raw));\n },\n\n contentType: \"application/msgpack\",\n};\n\n// ============================================================================\n// SERIALIZER FACTORY\n// ============================================================================\n\n/**\n * Get a serializer by format name.\n *\n * @param format - The serialization format (\"json\" or \"msgpack\")\n * @returns The corresponding serializer instance\n *\n * @example\n * ```typescript\n * const serializer = getSerializer('json');\n * const encoded = serializer.encode({ foo: 'bar' });\n * const decoded = serializer.decode(encoded);\n * ```\n */\nexport function getSerializer(format: \"json\" | \"msgpack\"): Serializer {\n switch (format) {\n case \"json\":\n return jsonSerializer;\n case \"msgpack\":\n return msgpackSerializer;\n default:\n return jsonSerializer;\n }\n}\n\n/**\n * Create a custom serializer with provided encode/decode functions.\n *\n * @param options - Serializer configuration\n * @param options.encode - Function to encode data to string or ArrayBuffer\n * @param options.decode - Function to decode string or ArrayBuffer to data\n * @param options.contentType - HTTP content type for the serialization format\n * @returns A custom serializer instance\n *\n * @example\n * ```typescript\n * const customSerializer = createSerializer({\n * encode: (data) => btoa(JSON.stringify(data)),\n * decode: (raw) => JSON.parse(atob(raw as string)),\n * contentType: 'application/x-custom',\n * });\n * ```\n */\nexport function createSerializer(options: {\n encode: (data: unknown) => string | ArrayBuffer;\n decode: (raw: string | ArrayBuffer) => unknown;\n contentType: string;\n}): Serializer {\n return options;\n}\n","/**\n * @parsrun/service - HTTP RPC Transport\n * HTTP-based transport for distributed services\n */\n\nimport type { RpcRequest, RpcResponse, RpcTransport } from \"../../types.js\";\nimport { type Serializer, jsonSerializer } from \"../../serialization/index.js\";\nimport { TransportError, SerializationError } from \"../errors.js\";\n\n// ============================================================================\n// HTTP TRANSPORT\n// ============================================================================\n\n/**\n * Options for creating an HTTP transport.\n */\nexport interface HttpTransportOptions {\n /** Base URL of the service */\n baseUrl: string;\n /** Custom serializer (default: JSON) */\n serializer?: Serializer;\n /** Custom headers */\n headers?: Record<string, string>;\n /** Fetch function (for testing or custom implementations) */\n fetch?: typeof globalThis.fetch;\n /** Request timeout in ms */\n timeout?: number;\n}\n\n/**\n * HTTP transport for RPC calls over HTTP/HTTPS.\n * Makes POST requests to /rpc endpoint with serialized request body.\n */\nexport class HttpTransport implements RpcTransport {\n readonly name = \"http\";\n private readonly baseUrl: string;\n private readonly serializer: Serializer;\n private readonly headers: Record<string, string>;\n private readonly fetchFn: typeof globalThis.fetch;\n private readonly timeout: number;\n\n constructor(options: HttpTransportOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\"); // Remove trailing slash\n this.serializer = options.serializer ?? jsonSerializer;\n this.headers = options.headers ?? {};\n this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.timeout = options.timeout ?? 30_000;\n }\n\n async call<TInput, TOutput>(request: RpcRequest<TInput>): Promise<RpcResponse<TOutput>> {\n const url = `${this.baseUrl}/rpc`;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n // Serialize request\n let body: string | ArrayBuffer;\n try {\n body = this.serializer.encode(request);\n } catch (error) {\n throw new SerializationError(\n \"Failed to serialize request\",\n error instanceof Error ? error : undefined\n );\n }\n\n // Make HTTP request\n const response = await this.fetchFn(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": this.serializer.contentType,\n Accept: this.serializer.contentType,\n \"X-Request-ID\": request.id,\n \"X-Service\": request.service,\n \"X-Method\": request.method,\n \"X-Method-Type\": request.type,\n ...(request.version ? { \"X-Service-Version\": request.version } : {}),\n ...(request.traceContext\n ? {\n traceparent: formatTraceparent(request.traceContext),\n ...(request.traceContext.traceState\n ? { tracestate: request.traceContext.traceState }\n : {}),\n }\n : {}),\n ...this.headers,\n },\n body: body instanceof ArrayBuffer ? body : body,\n signal: controller.signal,\n });\n\n // Parse response\n let responseData: RpcResponse<TOutput>;\n try {\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n if (contentType.includes(\"msgpack\")) {\n const buffer = await response.arrayBuffer();\n responseData = this.serializer.decode(buffer) as RpcResponse<TOutput>;\n } else {\n const text = await response.text();\n responseData = this.serializer.decode(text) as RpcResponse<TOutput>;\n }\n } catch (error) {\n throw new SerializationError(\n \"Failed to deserialize response\",\n error instanceof Error ? error : undefined\n );\n }\n\n return responseData;\n } catch (error) {\n if (error instanceof SerializationError) {\n throw error;\n }\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n throw new TransportError(`Request timeout after ${this.timeout}ms`);\n }\n throw new TransportError(`HTTP request failed: ${error.message}`, error);\n }\n\n throw new TransportError(\"Unknown transport error\");\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async close(): Promise<void> {\n // No persistent connection to close\n }\n}\n\n/**\n * Create an HTTP transport for RPC calls.\n *\n * @param options - Transport configuration options\n * @returns A new HTTP transport instance\n *\n * @example\n * ```typescript\n * const transport = createHttpTransport({\n * baseUrl: 'https://api.example.com',\n * timeout: 5000,\n * });\n * ```\n */\nexport function createHttpTransport(options: HttpTransportOptions): HttpTransport {\n return new HttpTransport(options);\n}\n\n// ============================================================================\n// TRACE CONTEXT HELPERS\n// ============================================================================\n\nimport type { TraceContext } from \"../../types.js\";\n\n/**\n * Format trace context as W3C traceparent header\n */\nfunction formatTraceparent(ctx: TraceContext): string {\n const flags = ctx.traceFlags.toString(16).padStart(2, \"0\");\n return `00-${ctx.traceId}-${ctx.spanId}-${flags}`;\n}\n\n/**\n * Parse W3C traceparent header to extract trace context.\n *\n * @param header - The traceparent header value\n * @returns Parsed trace context or null if invalid\n *\n * @example\n * ```typescript\n * const ctx = parseTraceparent('00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01');\n * // { traceId: '0af7651916cd43dd8448eb211c80319c', spanId: 'b7ad6b7169203331', traceFlags: 1 }\n * ```\n */\nexport function parseTraceparent(header: string): TraceContext | null {\n const parts = header.split(\"-\");\n if (parts.length !== 4) {\n return null;\n }\n\n const [version, traceId, spanId, flags] = parts;\n if (version !== \"00\" || !traceId || !spanId || !flags) {\n return null;\n }\n\n if (traceId.length !== 32 || spanId.length !== 16 || flags.length !== 2) {\n return null;\n }\n\n return {\n traceId,\n spanId,\n traceFlags: parseInt(flags, 16),\n };\n}\n\n// ============================================================================\n// HTTP SERVER ADAPTER\n// ============================================================================\n\nimport type { RpcServer } from \"../server.js\";\n\n/**\n * Create HTTP request handler for RPC server.\n * Can be used with Hono, Express, or any HTTP framework.\n *\n * @param server - The RPC server to handle requests\n * @returns Request handler function for HTTP frameworks\n *\n * @example\n * ```typescript\n * const handler = createHttpHandler(rpcServer);\n * // With Hono\n * app.post('/rpc', (c) => handler(c.req.raw));\n * ```\n */\nexport function createHttpHandler(server: RpcServer) {\n return async (request: Request): Promise<Response> => {\n try {\n // Parse request body\n const contentType = request.headers.get(\"Content-Type\") ?? \"application/json\";\n let body: unknown;\n\n if (contentType.includes(\"msgpack\")) {\n const buffer = await request.arrayBuffer();\n // For msgpack, we'd need to decode - using JSON for now\n body = JSON.parse(new TextDecoder().decode(buffer));\n } else {\n body = await request.json();\n }\n\n const rpcRequest = body as RpcRequest;\n\n // Parse trace context\n const traceparent = request.headers.get(\"traceparent\");\n if (traceparent) {\n const traceContext = parseTraceparent(traceparent);\n if (traceContext) {\n const tracestate = request.headers.get(\"tracestate\");\n if (tracestate) {\n traceContext.traceState = tracestate;\n }\n rpcRequest.traceContext = traceContext;\n }\n }\n\n // Handle request\n const response = await server.handle(rpcRequest);\n\n // Return response\n return new Response(JSON.stringify(response), {\n status: response.success ? 200 : getHttpStatus(response.error?.code),\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Request-ID\": rpcRequest.id,\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return new Response(\n JSON.stringify({\n success: false,\n error: {\n code: \"INTERNAL_ERROR\",\n message,\n },\n }),\n {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n }\n );\n }\n };\n}\n\n/**\n * Map error code to HTTP status\n */\nfunction getHttpStatus(code?: string): number {\n switch (code) {\n case \"METHOD_NOT_FOUND\":\n case \"SERVICE_NOT_FOUND\":\n return 404;\n case \"VERSION_MISMATCH\":\n case \"VALIDATION_ERROR\":\n case \"SERIALIZATION_ERROR\":\n return 400;\n case \"UNAUTHORIZED\":\n return 401;\n case \"FORBIDDEN\":\n return 403;\n case \"TIMEOUT\":\n return 504;\n case \"CIRCUIT_OPEN\":\n case \"BULKHEAD_REJECTED\":\n return 503;\n default:\n return 500;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -22,11 +22,36 @@ declare const jsonSerializer: Serializer;
|
|
|
22
22
|
*/
|
|
23
23
|
declare const msgpackSerializer: Serializer;
|
|
24
24
|
/**
|
|
25
|
-
* Get serializer by format name
|
|
25
|
+
* Get a serializer by format name.
|
|
26
|
+
*
|
|
27
|
+
* @param format - The serialization format ("json" or "msgpack")
|
|
28
|
+
* @returns The corresponding serializer instance
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const serializer = getSerializer('json');
|
|
33
|
+
* const encoded = serializer.encode({ foo: 'bar' });
|
|
34
|
+
* const decoded = serializer.decode(encoded);
|
|
35
|
+
* ```
|
|
26
36
|
*/
|
|
27
37
|
declare function getSerializer(format: "json" | "msgpack"): Serializer;
|
|
28
38
|
/**
|
|
29
|
-
* Create a custom serializer
|
|
39
|
+
* Create a custom serializer with provided encode/decode functions.
|
|
40
|
+
*
|
|
41
|
+
* @param options - Serializer configuration
|
|
42
|
+
* @param options.encode - Function to encode data to string or ArrayBuffer
|
|
43
|
+
* @param options.decode - Function to decode string or ArrayBuffer to data
|
|
44
|
+
* @param options.contentType - HTTP content type for the serialization format
|
|
45
|
+
* @returns A custom serializer instance
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const customSerializer = createSerializer({
|
|
50
|
+
* encode: (data) => btoa(JSON.stringify(data)),
|
|
51
|
+
* decode: (raw) => JSON.parse(atob(raw as string)),
|
|
52
|
+
* contentType: 'application/x-custom',
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
30
55
|
*/
|
|
31
56
|
declare function createSerializer(options: {
|
|
32
57
|
encode: (data: unknown) => string | ArrayBuffer;
|