Skip to content

Commit a3e2682

Browse files
committed
refactor: move types and errors out of core
1 parent c11a80b commit a3e2682

14 files changed

Lines changed: 988 additions & 0 deletions

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export default defineConfig({
4949
{ text: 'Why Trotsky', link: '/guide/why' },
5050
{ text: 'Features', link: '/guide/features' },
5151
{ text: 'Code of Conduct', link: '/guide/code-of-conduct' },
52+
{ text: 'Architecture', link: '/guide/architecture' },
5253
{ text: 'FAQ', link: '/guide/faq' },
5354
]
5455
},

lib/config/TrotskyConfig.ts

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/**
2+
* Configuration options for Trotsky instance.
3+
*
4+
* This module provides configuration interfaces and default values
5+
* for customizing Trotsky's behavior.
6+
*
7+
* @module config
8+
*/
9+
10+
/**
11+
* Logging configuration options.
12+
*
13+
* @public
14+
*/
15+
export interface LoggingConfig {
16+
/** Enable or disable logging */
17+
enabled: boolean
18+
/** Minimum log level to output */
19+
level: "debug" | "info" | "warn" | "error"
20+
/** Custom logger function (optional) */
21+
logger?: (level: string, message: string, meta?: Record<string, unknown>) => void
22+
}
23+
24+
/**
25+
* Pagination configuration options.
26+
*
27+
* @public
28+
*/
29+
export interface PaginationConfig {
30+
/** Default page size for paginated requests */
31+
defaultLimit: number
32+
/** Maximum page size allowed */
33+
maxLimit: number
34+
/** Enable automatic pagination */
35+
autoPaginate: boolean
36+
}
37+
38+
/**
39+
* Retry configuration options.
40+
*
41+
* @public
42+
*/
43+
export interface RetryConfig {
44+
/** Enable automatic retries on failure */
45+
enabled: boolean
46+
/** Maximum number of retry attempts */
47+
maxAttempts: number
48+
/** Backoff strategy for retries */
49+
backoff: "linear" | "exponential"
50+
/** Initial delay between retries (milliseconds) */
51+
initialDelay: number
52+
/** Maximum delay between retries (milliseconds) */
53+
maxDelay: number
54+
/** HTTP status codes that should trigger a retry */
55+
retryableStatusCodes: number[]
56+
}
57+
58+
/**
59+
* Rate limiting configuration options.
60+
*
61+
* @public
62+
*/
63+
export interface RateLimitConfig {
64+
/** Enable built-in rate limiting */
65+
enabled: boolean
66+
/** Maximum requests per minute */
67+
requestsPerMinute: number
68+
/** Maximum concurrent requests */
69+
concurrentRequests: number
70+
/** Behavior when rate limit is hit */
71+
onLimitReached: "throw" | "queue" | "drop"
72+
}
73+
74+
/**
75+
* Caching configuration options.
76+
*
77+
* @public
78+
*/
79+
export interface CacheConfig {
80+
/** Enable caching */
81+
enabled: boolean
82+
/** Default cache TTL in milliseconds */
83+
defaultTTL: number
84+
/** Maximum cache size (number of entries) */
85+
maxSize: number
86+
/** Cache key prefix */
87+
keyPrefix: string
88+
}
89+
90+
/**
91+
* Complete Trotsky configuration.
92+
*
93+
* @public
94+
*/
95+
export interface TrotskyConfig {
96+
/** Logging configuration */
97+
logging: LoggingConfig
98+
/** Pagination configuration */
99+
pagination: PaginationConfig
100+
/** Retry configuration */
101+
retry: RetryConfig
102+
/** Rate limiting configuration */
103+
rateLimit: RateLimitConfig
104+
/** Caching configuration */
105+
cache: CacheConfig
106+
}
107+
108+
/**
109+
* Partial configuration allowing users to override specific options.
110+
*
111+
* @public
112+
*/
113+
export type PartialTrotskyConfig = {
114+
[K in keyof TrotskyConfig]?: Partial<TrotskyConfig[K]>
115+
}
116+
117+
/**
118+
* Default configuration values.
119+
*
120+
* These values are used when no custom configuration is provided.
121+
*
122+
* @public
123+
*/
124+
export const defaultConfig: TrotskyConfig = {
125+
logging: {
126+
enabled: false,
127+
level: "info"
128+
},
129+
pagination: {
130+
defaultLimit: 50,
131+
maxLimit: 100,
132+
autoPaginate: true
133+
},
134+
retry: {
135+
enabled: true,
136+
maxAttempts: 3,
137+
backoff: "exponential",
138+
initialDelay: 1000,
139+
maxDelay: 30000,
140+
retryableStatusCodes: [408, 429, 500, 502, 503, 504]
141+
},
142+
rateLimit: {
143+
enabled: false,
144+
requestsPerMinute: 60,
145+
concurrentRequests: 10,
146+
onLimitReached: "queue"
147+
},
148+
cache: {
149+
enabled: false,
150+
defaultTTL: 60000, // 1 minute
151+
maxSize: 1000,
152+
keyPrefix: "trotsky:"
153+
}
154+
}
155+
156+
/**
157+
* Merges partial configuration with default configuration.
158+
*
159+
* @param config - Partial configuration to merge
160+
* @returns Complete configuration with defaults
161+
*
162+
* @example
163+
* ```ts
164+
* const config = mergeConfig({
165+
* logging: { enabled: true, level: "debug" }
166+
* })
167+
* ```
168+
*
169+
* @public
170+
*/
171+
export function mergeConfig (config?: PartialTrotskyConfig): TrotskyConfig {
172+
if (!config) {
173+
return { ...defaultConfig }
174+
}
175+
176+
return {
177+
logging: { ...defaultConfig.logging, ...config.logging },
178+
pagination: { ...defaultConfig.pagination, ...config.pagination },
179+
retry: { ...defaultConfig.retry, ...config.retry },
180+
rateLimit: { ...defaultConfig.rateLimit, ...config.rateLimit },
181+
cache: { ...defaultConfig.cache, ...config.cache }
182+
}
183+
}

lib/config/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Central export point for Trotsky configuration.
3+
*
4+
* @module config
5+
* @packageDocumentation
6+
*/
7+
8+
export type {
9+
LoggingConfig,
10+
PaginationConfig,
11+
RetryConfig,
12+
RateLimitConfig,
13+
CacheConfig,
14+
TrotskyConfig,
15+
PartialTrotskyConfig
16+
} from "./TrotskyConfig"
17+
18+
export {
19+
defaultConfig,
20+
mergeConfig
21+
} from "./TrotskyConfig"

lib/errors/AuthenticationError.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Error class for authentication and authorization failures.
3+
*
4+
* Thrown when authentication is required but missing, invalid,
5+
* or when the user lacks permission for an operation.
6+
*
7+
* @example
8+
* ```ts
9+
* throw new AuthenticationError(
10+
* "Authentication required for this operation",
11+
* "AUTH_REQUIRED",
12+
* "StepActorFollow"
13+
* )
14+
* ```
15+
*
16+
* @public
17+
*/
18+
19+
import { TrotskyError } from "./TrotskyError"
20+
21+
export class AuthenticationError extends TrotskyError {
22+
/**
23+
* Creates a new AuthenticationError.
24+
*
25+
* @param message - Human-readable error message
26+
* @param code - Machine-readable error code
27+
* @param step - Optional step name where error occurred
28+
* @param cause - Optional underlying error
29+
*/
30+
constructor (
31+
message: string,
32+
code: string = "AUTH_ERROR",
33+
step?: string,
34+
cause?: Error
35+
) {
36+
super(message, code, step, cause)
37+
this.name = "AuthenticationError"
38+
}
39+
}
40+
41+
/**
42+
* Common authentication error codes.
43+
*
44+
* @public
45+
*/
46+
export const AuthenticationErrorCode = {
47+
/** Authentication is required but not provided */
48+
AUTH_REQUIRED: "AUTH_REQUIRED",
49+
/** Provided credentials are invalid */
50+
INVALID_CREDENTIALS: "INVALID_CREDENTIALS",
51+
/** Session has expired */
52+
SESSION_EXPIRED: "SESSION_EXPIRED",
53+
/** User lacks permission for this operation */
54+
FORBIDDEN: "FORBIDDEN",
55+
/** Agent is not authenticated */
56+
NOT_AUTHENTICATED: "NOT_AUTHENTICATED"
57+
} as const

lib/errors/PaginationError.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Error class for pagination-related failures.
3+
*
4+
* Thrown when pagination operations fail, such as invalid cursors,
5+
* cursor expiration, or pagination API errors.
6+
*
7+
* @example
8+
* ```ts
9+
* throw new PaginationError(
10+
* "Invalid pagination cursor",
11+
* "INVALID_CURSOR",
12+
* "StepActorFollowers"
13+
* )
14+
* ```
15+
*
16+
* @public
17+
*/
18+
19+
import { TrotskyError } from "./TrotskyError"
20+
21+
export class PaginationError extends TrotskyError {
22+
/**
23+
* Creates a new PaginationError.
24+
*
25+
* @param message - Human-readable error message
26+
* @param code - Machine-readable error code
27+
* @param step - Optional step name where error occurred
28+
* @param cause - Optional underlying error
29+
*/
30+
constructor (
31+
message: string,
32+
code: string = "PAGINATION_ERROR",
33+
step?: string,
34+
cause?: Error
35+
) {
36+
super(message, code, step, cause)
37+
this.name = "PaginationError"
38+
}
39+
}
40+
41+
/**
42+
* Common pagination error codes.
43+
*
44+
* @public
45+
*/
46+
export const PaginationErrorCode = {
47+
/** Cursor is invalid or malformed */
48+
INVALID_CURSOR: "INVALID_CURSOR",
49+
/** Cursor has expired */
50+
CURSOR_EXPIRED: "CURSOR_EXPIRED",
51+
/** Failed to fetch next page */
52+
FETCH_FAILED: "FETCH_FAILED",
53+
/** Limit parameter is invalid */
54+
INVALID_LIMIT: "INVALID_LIMIT",
55+
/** No more pages available */
56+
NO_MORE_PAGES: "NO_MORE_PAGES"
57+
} as const

0 commit comments

Comments
 (0)