@k-msg/core 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @k-msg/core
2
2
 
3
- Core library for the K-Message platform. Provides foundational functionality including type definitions, error handling, retry logic, and platform interfaces.
3
+ The foundational package of the K-Message platform, providing essential types, error handling, retry mechanisms, and platform interfaces for Korean multi-channel messaging.
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,12 +12,29 @@ bun add @k-msg/core
12
12
 
13
13
  ## Features
14
14
 
15
- - **AlimTalkPlatform**: Core messaging platform interface
16
- - **Error Handling**: Comprehensive error types and handling logic
17
- - **Retry Mechanism**: Automatic retry for network failures
18
- - **Health Checks**: System health monitoring and diagnostics
15
+ ### 🏗️ **Core Platform Interface**
16
+ - **AlimTalkPlatform**: Unified messaging platform abstraction
17
+ - **Provider Management**: Multi-provider support and switching
18
+ - **Feature Flags**: Configurable platform capabilities
19
19
 
20
- ## Basic Usage
20
+ ### ⚠️ **Comprehensive Error Handling**
21
+ - **KMessageError Hierarchy**: Structured error types for different scenarios
22
+ - **Error Context**: Rich error information with operation context
23
+ - **Error Recovery**: Built-in fallback and recovery strategies
24
+
25
+ ### 🔄 **Retry & Resilience**
26
+ - **Exponential Backoff**: Smart retry with increasing delays
27
+ - **Circuit Breaker**: Automatic failure protection
28
+ - **Jitter**: Randomized delays to prevent thundering herd
29
+
30
+ ### 💊 **Health Monitoring**
31
+ - **System Health Checks**: Multi-component health validation
32
+ - **Service Discovery**: Dynamic provider health monitoring
33
+ - **Dependency Tracking**: External service availability checks
34
+
35
+ ## Quick Start
36
+
37
+ ### Basic Platform Setup
21
38
 
22
39
  ```typescript
23
40
  import { AlimTalkPlatform } from '@k-msg/core';
@@ -32,29 +49,239 @@ const platform = new AlimTalkPlatform({
32
49
  }
33
50
  });
34
51
 
35
- // Get platform information
52
+ // Get platform capabilities
36
53
  const info = platform.getInfo();
37
- console.log(info);
54
+ console.log(`Platform: ${info.name}, Version: ${info.version}`);
55
+ console.log(`Supported providers: ${info.supportedProviders.join(', ')}`);
38
56
 
39
- // Perform health check
57
+ // Perform comprehensive health check
40
58
  const health = await platform.healthCheck();
41
- console.log(health);
59
+ console.log(`Health: ${health.status}, Services: ${Object.keys(health.services).length}`);
42
60
  ```
43
61
 
44
- ## Error Handling
62
+ ### Error Handling Patterns
45
63
 
46
64
  ```typescript
47
- import { KMessageError, Result } from '@k-msg/core';
65
+ import { KMessageError, KMessageErrorCode, Result } from '@k-msg/core';
66
+
67
+ // Method 1: Result Pattern (Recommended)
68
+ const result = await Result.fromPromise(
69
+ provider.sendMessage(message)
70
+ );
48
71
 
49
- // Using Result pattern
50
- const result = await Result.fromPromise(someAsyncOperation());
51
72
  if (result.isSuccess) {
52
- console.log(result.data);
73
+ console.log(`Message sent: ${result.data.messageId}`);
53
74
  } else {
54
- console.error(result.error);
75
+ console.error(`Send failed: ${result.error.message}`);
76
+
77
+ // Handle specific error types
78
+ if (result.error.code === KMessageErrorCode.PROVIDER_TIMEOUT) {
79
+ // Retry with different provider
80
+ } else if (result.error.code === KMessageErrorCode.TEMPLATE_NOT_FOUND) {
81
+ // Create template or use fallback
82
+ }
83
+ }
84
+
85
+ // Method 2: Try-Catch with Structured Errors
86
+ try {
87
+ const response = await provider.sendMessage(message);
88
+ console.log('Success:', response);
89
+ } catch (error) {
90
+ if (error instanceof KMessageError) {
91
+ console.error(`[${error.code}] ${error.message}`);
92
+ console.error('Context:', error.context);
93
+
94
+ // Access original cause if available
95
+ if (error.cause) {
96
+ console.error('Root cause:', error.cause);
97
+ }
98
+ } else {
99
+ // Handle unexpected errors
100
+ console.error('Unexpected error:', error);
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### Retry Configuration
106
+
107
+ ```typescript
108
+ import { RetryManager, RetryConfig } from '@k-msg/core';
109
+
110
+ // Custom retry configuration
111
+ const retryConfig: RetryConfig = {
112
+ maxAttempts: 3,
113
+ baseDelay: 1000, // 1 second
114
+ maxDelay: 10000, // 10 seconds
115
+ backoffMultiplier: 2,
116
+ jitterType: 'full', // full, half, none
117
+ retryableErrors: [
118
+ KMessageErrorCode.NETWORK_ERROR,
119
+ KMessageErrorCode.PROVIDER_TIMEOUT,
120
+ KMessageErrorCode.RATE_LIMIT_EXCEEDED
121
+ ]
122
+ };
123
+
124
+ const retryManager = new RetryManager(retryConfig);
125
+
126
+ // Execute with retry
127
+ const result = await retryManager.execute(async () => {
128
+ return await provider.sendMessage(message);
129
+ });
130
+ ```
131
+
132
+ ### Health Check Implementation
133
+
134
+ ```typescript
135
+ import { HealthChecker, HealthStatus } from '@k-msg/core';
136
+
137
+ const healthChecker = new HealthChecker();
138
+
139
+ // Register custom health checks
140
+ healthChecker.register('database', async () => {
141
+ const connected = await checkDatabaseConnection();
142
+ return {
143
+ status: connected ? HealthStatus.HEALTHY : HealthStatus.UNHEALTHY,
144
+ details: { connected, lastCheck: new Date() }
145
+ };
146
+ });
147
+
148
+ healthChecker.register('external-api', async () => {
149
+ const responseTime = await measureApiResponseTime();
150
+ return {
151
+ status: responseTime < 1000 ? HealthStatus.HEALTHY : HealthStatus.DEGRADED,
152
+ details: { responseTime, threshold: 1000 }
153
+ };
154
+ });
155
+
156
+ // Perform comprehensive health check
157
+ const overallHealth = await healthChecker.checkAll();
158
+ console.log(`Overall status: ${overallHealth.status}`);
159
+ console.log(`Healthy services: ${overallHealth.healthyCount}/${overallHealth.totalCount}`);
160
+ ```
161
+
162
+ ## API Reference
163
+
164
+ ### Core Types
165
+
166
+ ```typescript
167
+ // Platform configuration
168
+ interface AlimTalkPlatformConfig {
169
+ providers: string[];
170
+ defaultProvider: string;
171
+ features: PlatformFeatures;
172
+ retryConfig?: RetryConfig;
173
+ healthCheckConfig?: HealthCheckConfig;
174
+ }
175
+
176
+ // Error types
177
+ enum KMessageErrorCode {
178
+ UNKNOWN = 'UNKNOWN',
179
+ NETWORK_ERROR = 'NETWORK_ERROR',
180
+ PROVIDER_ERROR = 'PROVIDER_ERROR',
181
+ TEMPLATE_ERROR = 'TEMPLATE_ERROR',
182
+ VALIDATION_ERROR = 'VALIDATION_ERROR',
183
+ RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',
184
+ // ... more error codes
55
185
  }
186
+
187
+ // Health check results
188
+ interface HealthCheckResult {
189
+ status: HealthStatus;
190
+ services: Record<string, ServiceHealthInfo>;
191
+ timestamp: Date;
192
+ totalChecks: number;
193
+ passedChecks: number;
194
+ }
195
+ ```
196
+
197
+ ### Test Utilities
198
+
199
+ ```typescript
200
+ import { TestData, TestAssertions } from '@k-msg/core/test-utils';
201
+
202
+ // Generate test data
203
+ const testMessage = TestData.createMessage({
204
+ provider: 'iwinv',
205
+ templateCode: 'AUTH_OTP',
206
+ phoneNumber: '01012345678'
207
+ });
208
+
209
+ // Test assertions
210
+ await TestAssertions.assertMessageSent(result);
211
+ TestAssertions.assertErrorType(error, KMessageErrorCode.TEMPLATE_NOT_FOUND);
56
212
  ```
57
213
 
214
+ ## Advanced Usage
215
+
216
+ ### Custom Error Types
217
+
218
+ ```typescript
219
+ import { KMessageError, KMessageErrorCode } from '@k-msg/core';
220
+
221
+ class CustomProviderError extends KMessageError {
222
+ constructor(
223
+ message: string,
224
+ public readonly providerId: string,
225
+ cause?: Error
226
+ ) {
227
+ super(
228
+ message,
229
+ KMessageErrorCode.PROVIDER_ERROR,
230
+ { operation: 'send_message', provider: providerId },
231
+ cause
232
+ );
233
+ }
234
+ }
235
+ ```
236
+
237
+ ### Plugin Integration
238
+
239
+ ```typescript
240
+ import { AlimTalkPlatform, PlatformPlugin } from '@k-msg/core';
241
+
242
+ class LoggingPlugin implements PlatformPlugin {
243
+ name = 'logging';
244
+
245
+ async initialize(platform: AlimTalkPlatform) {
246
+ platform.on('message_sent', (event) => {
247
+ console.log(`Message sent: ${event.messageId}`);
248
+ });
249
+
250
+ platform.on('error', (event) => {
251
+ console.error(`Error: ${event.error.message}`);
252
+ });
253
+ }
254
+ }
255
+
256
+ const platform = new AlimTalkPlatform(config);
257
+ await platform.use(new LoggingPlugin());
258
+ ```
259
+
260
+ ## Best Practices
261
+
262
+ 1. **Always use Result pattern** for error handling in production code
263
+ 2. **Configure retries** appropriately for your use case
264
+ 3. **Implement health checks** for all external dependencies
265
+ 4. **Use structured logging** with error context information
266
+ 5. **Monitor error rates** and adjust retry policies accordingly
267
+
268
+ ## Testing
269
+
270
+ ```bash
271
+ # Run unit tests
272
+ bun test
273
+
274
+ # Run with coverage
275
+ bun test --coverage
276
+
277
+ # Run specific test files
278
+ bun test retry.test.ts
279
+ ```
280
+
281
+ ## Contributing
282
+
283
+ See the main [CONTRIBUTING.md](../../CONTRIBUTING.md) for guidelines.
284
+
58
285
  ## License
59
286
 
60
- MIT
287
+ MIT License - see [LICENSE](../../LICENSE) for details.
@@ -0,0 +1,206 @@
1
+ import { z } from "zod";
2
+ import { LogLevel } from "./logger";
3
+ export declare const DatabaseConfigSchema: z.ZodObject<{
4
+ host: z.ZodDefault<z.ZodString>;
5
+ port: z.ZodDefault<z.ZodNumber>;
6
+ database: z.ZodString;
7
+ username: z.ZodString;
8
+ password: z.ZodString;
9
+ ssl: z.ZodDefault<z.ZodBoolean>;
10
+ maxConnections: z.ZodDefault<z.ZodNumber>;
11
+ connectionTimeout: z.ZodDefault<z.ZodNumber>;
12
+ }, z.core.$strip>;
13
+ export declare const RedisConfigSchema: z.ZodObject<{
14
+ host: z.ZodDefault<z.ZodString>;
15
+ port: z.ZodDefault<z.ZodNumber>;
16
+ password: z.ZodOptional<z.ZodString>;
17
+ db: z.ZodDefault<z.ZodNumber>;
18
+ keyPrefix: z.ZodDefault<z.ZodString>;
19
+ maxRetries: z.ZodDefault<z.ZodNumber>;
20
+ }, z.core.$strip>;
21
+ export declare const LoggerConfigSchema: z.ZodObject<{
22
+ level: z.ZodDefault<z.ZodEnum<typeof LogLevel>>;
23
+ enableConsole: z.ZodDefault<z.ZodBoolean>;
24
+ enableFile: z.ZodDefault<z.ZodBoolean>;
25
+ filePath: z.ZodOptional<z.ZodString>;
26
+ maxFileSize: z.ZodDefault<z.ZodNumber>;
27
+ maxFiles: z.ZodDefault<z.ZodNumber>;
28
+ enableJson: z.ZodDefault<z.ZodBoolean>;
29
+ enableColors: z.ZodDefault<z.ZodBoolean>;
30
+ }, z.core.$strip>;
31
+ export declare const HealthConfigSchema: z.ZodObject<{
32
+ timeout: z.ZodDefault<z.ZodNumber>;
33
+ interval: z.ZodDefault<z.ZodNumber>;
34
+ retries: z.ZodDefault<z.ZodNumber>;
35
+ includeMetrics: z.ZodDefault<z.ZodBoolean>;
36
+ }, z.core.$strip>;
37
+ export declare const IWINVConfigSchema: z.ZodObject<{
38
+ apiKey: z.ZodString;
39
+ baseUrl: z.ZodDefault<z.ZodString>;
40
+ timeout: z.ZodDefault<z.ZodNumber>;
41
+ retryAttempts: z.ZodDefault<z.ZodNumber>;
42
+ retryDelay: z.ZodDefault<z.ZodNumber>;
43
+ debug: z.ZodDefault<z.ZodBoolean>;
44
+ rateLimit: z.ZodDefault<z.ZodObject<{
45
+ requests: z.ZodDefault<z.ZodNumber>;
46
+ perSecond: z.ZodDefault<z.ZodNumber>;
47
+ }, z.core.$strip>>;
48
+ }, z.core.$strip>;
49
+ export declare const SMSConfigSchema: z.ZodObject<{
50
+ provider: z.ZodEnum<{
51
+ iwinv: "iwinv";
52
+ aligo: "aligo";
53
+ coolsms: "coolsms";
54
+ }>;
55
+ apiKey: z.ZodString;
56
+ apiSecret: z.ZodOptional<z.ZodString>;
57
+ senderId: z.ZodString;
58
+ defaultCountryCode: z.ZodDefault<z.ZodString>;
59
+ timeout: z.ZodDefault<z.ZodNumber>;
60
+ }, z.core.$strip>;
61
+ export declare const ServerConfigSchema: z.ZodObject<{
62
+ port: z.ZodDefault<z.ZodNumber>;
63
+ host: z.ZodDefault<z.ZodString>;
64
+ cors: z.ZodDefault<z.ZodObject<{
65
+ origins: z.ZodDefault<z.ZodArray<z.ZodString>>;
66
+ credentials: z.ZodDefault<z.ZodBoolean>;
67
+ }, z.core.$strip>>;
68
+ maxRequestSize: z.ZodDefault<z.ZodNumber>;
69
+ requestTimeout: z.ZodDefault<z.ZodNumber>;
70
+ enableMetrics: z.ZodDefault<z.ZodBoolean>;
71
+ enableDocs: z.ZodDefault<z.ZodBoolean>;
72
+ }, z.core.$strip>;
73
+ export declare const QueueConfigSchema: z.ZodObject<{
74
+ maxConcurrency: z.ZodDefault<z.ZodNumber>;
75
+ maxRetries: z.ZodDefault<z.ZodNumber>;
76
+ retryDelay: z.ZodDefault<z.ZodNumber>;
77
+ maxAge: z.ZodDefault<z.ZodNumber>;
78
+ batchSize: z.ZodDefault<z.ZodNumber>;
79
+ processingInterval: z.ZodDefault<z.ZodNumber>;
80
+ }, z.core.$strip>;
81
+ export declare const KMessageConfigSchema: z.ZodObject<{
82
+ environment: z.ZodDefault<z.ZodEnum<{
83
+ development: "development";
84
+ staging: "staging";
85
+ production: "production";
86
+ }>>;
87
+ server: z.ZodDefault<z.ZodObject<{
88
+ port: z.ZodDefault<z.ZodNumber>;
89
+ host: z.ZodDefault<z.ZodString>;
90
+ cors: z.ZodDefault<z.ZodObject<{
91
+ origins: z.ZodDefault<z.ZodArray<z.ZodString>>;
92
+ credentials: z.ZodDefault<z.ZodBoolean>;
93
+ }, z.core.$strip>>;
94
+ maxRequestSize: z.ZodDefault<z.ZodNumber>;
95
+ requestTimeout: z.ZodDefault<z.ZodNumber>;
96
+ enableMetrics: z.ZodDefault<z.ZodBoolean>;
97
+ enableDocs: z.ZodDefault<z.ZodBoolean>;
98
+ }, z.core.$strip>>;
99
+ database: z.ZodOptional<z.ZodObject<{
100
+ host: z.ZodDefault<z.ZodString>;
101
+ port: z.ZodDefault<z.ZodNumber>;
102
+ database: z.ZodString;
103
+ username: z.ZodString;
104
+ password: z.ZodString;
105
+ ssl: z.ZodDefault<z.ZodBoolean>;
106
+ maxConnections: z.ZodDefault<z.ZodNumber>;
107
+ connectionTimeout: z.ZodDefault<z.ZodNumber>;
108
+ }, z.core.$strip>>;
109
+ redis: z.ZodOptional<z.ZodObject<{
110
+ host: z.ZodDefault<z.ZodString>;
111
+ port: z.ZodDefault<z.ZodNumber>;
112
+ password: z.ZodOptional<z.ZodString>;
113
+ db: z.ZodDefault<z.ZodNumber>;
114
+ keyPrefix: z.ZodDefault<z.ZodString>;
115
+ maxRetries: z.ZodDefault<z.ZodNumber>;
116
+ }, z.core.$strip>>;
117
+ logger: z.ZodDefault<z.ZodObject<{
118
+ level: z.ZodDefault<z.ZodEnum<typeof LogLevel>>;
119
+ enableConsole: z.ZodDefault<z.ZodBoolean>;
120
+ enableFile: z.ZodDefault<z.ZodBoolean>;
121
+ filePath: z.ZodOptional<z.ZodString>;
122
+ maxFileSize: z.ZodDefault<z.ZodNumber>;
123
+ maxFiles: z.ZodDefault<z.ZodNumber>;
124
+ enableJson: z.ZodDefault<z.ZodBoolean>;
125
+ enableColors: z.ZodDefault<z.ZodBoolean>;
126
+ }, z.core.$strip>>;
127
+ health: z.ZodDefault<z.ZodObject<{
128
+ timeout: z.ZodDefault<z.ZodNumber>;
129
+ interval: z.ZodDefault<z.ZodNumber>;
130
+ retries: z.ZodDefault<z.ZodNumber>;
131
+ includeMetrics: z.ZodDefault<z.ZodBoolean>;
132
+ }, z.core.$strip>>;
133
+ queue: z.ZodDefault<z.ZodObject<{
134
+ maxConcurrency: z.ZodDefault<z.ZodNumber>;
135
+ maxRetries: z.ZodDefault<z.ZodNumber>;
136
+ retryDelay: z.ZodDefault<z.ZodNumber>;
137
+ maxAge: z.ZodDefault<z.ZodNumber>;
138
+ batchSize: z.ZodDefault<z.ZodNumber>;
139
+ processingInterval: z.ZodDefault<z.ZodNumber>;
140
+ }, z.core.$strip>>;
141
+ providers: z.ZodDefault<z.ZodObject<{
142
+ iwinv: z.ZodOptional<z.ZodObject<{
143
+ apiKey: z.ZodString;
144
+ baseUrl: z.ZodDefault<z.ZodString>;
145
+ timeout: z.ZodDefault<z.ZodNumber>;
146
+ retryAttempts: z.ZodDefault<z.ZodNumber>;
147
+ retryDelay: z.ZodDefault<z.ZodNumber>;
148
+ debug: z.ZodDefault<z.ZodBoolean>;
149
+ rateLimit: z.ZodDefault<z.ZodObject<{
150
+ requests: z.ZodDefault<z.ZodNumber>;
151
+ perSecond: z.ZodDefault<z.ZodNumber>;
152
+ }, z.core.$strip>>;
153
+ }, z.core.$strip>>;
154
+ sms: z.ZodOptional<z.ZodObject<{
155
+ provider: z.ZodEnum<{
156
+ iwinv: "iwinv";
157
+ aligo: "aligo";
158
+ coolsms: "coolsms";
159
+ }>;
160
+ apiKey: z.ZodString;
161
+ apiSecret: z.ZodOptional<z.ZodString>;
162
+ senderId: z.ZodString;
163
+ defaultCountryCode: z.ZodDefault<z.ZodString>;
164
+ timeout: z.ZodDefault<z.ZodNumber>;
165
+ }, z.core.$strip>>;
166
+ }, z.core.$strip>>;
167
+ features: z.ZodDefault<z.ZodObject<{
168
+ enableBulkSending: z.ZodDefault<z.ZodBoolean>;
169
+ enableScheduling: z.ZodDefault<z.ZodBoolean>;
170
+ enableAnalytics: z.ZodDefault<z.ZodBoolean>;
171
+ enableWebhooks: z.ZodDefault<z.ZodBoolean>;
172
+ enableTemplateCache: z.ZodDefault<z.ZodBoolean>;
173
+ maxTemplatesPerProvider: z.ZodDefault<z.ZodNumber>;
174
+ maxRecipientsPerBatch: z.ZodDefault<z.ZodNumber>;
175
+ }, z.core.$strip>>;
176
+ security: z.ZodDefault<z.ZodObject<{
177
+ apiKeyRequired: z.ZodDefault<z.ZodBoolean>;
178
+ rateLimitEnabled: z.ZodDefault<z.ZodBoolean>;
179
+ maxRequestsPerMinute: z.ZodDefault<z.ZodNumber>;
180
+ enableCors: z.ZodDefault<z.ZodBoolean>;
181
+ trustedProxies: z.ZodDefault<z.ZodArray<z.ZodString>>;
182
+ }, z.core.$strip>>;
183
+ }, z.core.$strip>;
184
+ export type DatabaseConfig = z.infer<typeof DatabaseConfigSchema>;
185
+ export type RedisConfig = z.infer<typeof RedisConfigSchema>;
186
+ export type ConfigLoggerConfig = z.infer<typeof LoggerConfigSchema>;
187
+ export type HealthConfig = z.infer<typeof HealthConfigSchema>;
188
+ export type IWINVConfig = z.infer<typeof IWINVConfigSchema>;
189
+ export type SMSConfig = z.infer<typeof SMSConfigSchema>;
190
+ export type ServerConfig = z.infer<typeof ServerConfigSchema>;
191
+ export type QueueConfig = z.infer<typeof QueueConfigSchema>;
192
+ export type KMessageConfig = z.infer<typeof KMessageConfigSchema>;
193
+ export declare class ConfigLoader {
194
+ static loadFromEnv(): KMessageConfig;
195
+ static loadFromFile(filePath: string): Promise<KMessageConfig>;
196
+ static validate(config: any): KMessageConfig;
197
+ static getDefaults(): KMessageConfig;
198
+ }
199
+ type DeepPartial<T> = {
200
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
201
+ };
202
+ export declare const developmentConfig: DeepPartial<KMessageConfig>;
203
+ export declare const productionConfig: DeepPartial<KMessageConfig>;
204
+ export declare function mergeConfigs(base: KMessageConfig, override: Partial<KMessageConfig>): KMessageConfig;
205
+ export declare function validateProviderConfig(provider: "iwinv" | "sms", config: any): any;
206
+ export {};
@@ -0,0 +1,27 @@
1
+ export declare enum KMsgErrorCode {
2
+ INVALID_REQUEST = "INVALID_REQUEST",
3
+ AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED",
4
+ INSUFFICIENT_BALANCE = "INSUFFICIENT_BALANCE",
5
+ TEMPLATE_NOT_FOUND = "TEMPLATE_NOT_FOUND",
6
+ RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED",
7
+ NETWORK_ERROR = "NETWORK_ERROR",
8
+ NETWORK_TIMEOUT = "NETWORK_TIMEOUT",
9
+ NETWORK_SERVICE_UNAVAILABLE = "NETWORK_SERVICE_UNAVAILABLE",
10
+ PROVIDER_ERROR = "PROVIDER_ERROR",
11
+ MESSAGE_SEND_FAILED = "MESSAGE_SEND_FAILED",
12
+ UNKNOWN_ERROR = "UNKNOWN_ERROR"
13
+ }
14
+ export declare class KMsgError extends Error {
15
+ readonly code: KMsgErrorCode;
16
+ readonly details?: Record<string, any>;
17
+ constructor(code: KMsgErrorCode, message: string, details?: Record<string, any>);
18
+ toJSON(): {
19
+ name: string;
20
+ code: KMsgErrorCode;
21
+ message: string;
22
+ details: Record<string, any> | undefined;
23
+ };
24
+ }
25
+ export declare const ErrorUtils: {
26
+ isRetryable: (error: any) => boolean;
27
+ };
@@ -0,0 +1,39 @@
1
+ export interface HealthStatus {
2
+ healthy: boolean;
3
+ timestamp: Date;
4
+ uptime: number;
5
+ version?: string;
6
+ services?: Record<string, ServiceHealth>;
7
+ metrics?: Record<string, any>;
8
+ }
9
+ export interface ServiceHealth {
10
+ healthy: boolean;
11
+ latency?: number;
12
+ error?: string;
13
+ lastCheck?: Date;
14
+ }
15
+ export interface HealthCheckConfig {
16
+ timeout?: number;
17
+ interval?: number;
18
+ retries?: number;
19
+ includeMetrics?: boolean;
20
+ }
21
+ export declare class HealthChecker {
22
+ private config;
23
+ private startTime;
24
+ private services;
25
+ private lastCheck;
26
+ constructor(config?: HealthCheckConfig);
27
+ registerService(name: string, checkFn: () => Promise<ServiceHealth>): void;
28
+ unregisterService(name: string): boolean;
29
+ clearServices(): void;
30
+ checkHealth(): Promise<HealthStatus>;
31
+ getLastKnownStatus(): HealthStatus;
32
+ private timeoutPromise;
33
+ private calculateAverageLatency;
34
+ }
35
+ export declare class SimpleHealthChecker {
36
+ static database(): () => Promise<ServiceHealth>;
37
+ static external(url: string, timeout?: number): () => Promise<ServiceHealth>;
38
+ static memory(maxUsageMB?: number): () => Promise<ServiceHealth>;
39
+ }