@lithia-js/core 1.0.0-canary.0

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.
Files changed (91) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/CHANGELOG.md +13 -0
  3. package/LICENSE +21 -0
  4. package/README.md +60 -0
  5. package/dist/config.d.ts +101 -0
  6. package/dist/config.js +113 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/context/event-context.d.ts +53 -0
  9. package/dist/context/event-context.js +42 -0
  10. package/dist/context/event-context.js.map +1 -0
  11. package/dist/context/index.d.ts +16 -0
  12. package/dist/context/index.js +29 -0
  13. package/dist/context/index.js.map +1 -0
  14. package/dist/context/lithia-context.d.ts +47 -0
  15. package/dist/context/lithia-context.js +43 -0
  16. package/dist/context/lithia-context.js.map +1 -0
  17. package/dist/context/route-context.d.ts +74 -0
  18. package/dist/context/route-context.js +42 -0
  19. package/dist/context/route-context.js.map +1 -0
  20. package/dist/env.d.ts +1 -0
  21. package/dist/env.js +32 -0
  22. package/dist/env.js.map +1 -0
  23. package/dist/errors.d.ts +51 -0
  24. package/dist/errors.js +80 -0
  25. package/dist/errors.js.map +1 -0
  26. package/dist/hooks/dependency-hooks.d.ts +105 -0
  27. package/dist/hooks/dependency-hooks.js +96 -0
  28. package/dist/hooks/dependency-hooks.js.map +1 -0
  29. package/dist/hooks/event-hooks.d.ts +61 -0
  30. package/dist/hooks/event-hooks.js +70 -0
  31. package/dist/hooks/event-hooks.js.map +1 -0
  32. package/dist/hooks/index.d.ts +41 -0
  33. package/dist/hooks/index.js +59 -0
  34. package/dist/hooks/index.js.map +1 -0
  35. package/dist/hooks/route-hooks.d.ts +154 -0
  36. package/dist/hooks/route-hooks.js +174 -0
  37. package/dist/hooks/route-hooks.js.map +1 -0
  38. package/dist/lib.d.ts +10 -0
  39. package/dist/lib.js +30 -0
  40. package/dist/lib.js.map +1 -0
  41. package/dist/lithia.d.ts +447 -0
  42. package/dist/lithia.js +649 -0
  43. package/dist/lithia.js.map +1 -0
  44. package/dist/logger.d.ts +11 -0
  45. package/dist/logger.js +55 -0
  46. package/dist/logger.js.map +1 -0
  47. package/dist/module-loader.d.ts +12 -0
  48. package/dist/module-loader.js +78 -0
  49. package/dist/module-loader.js.map +1 -0
  50. package/dist/server/event-processor.d.ts +195 -0
  51. package/dist/server/event-processor.js +253 -0
  52. package/dist/server/event-processor.js.map +1 -0
  53. package/dist/server/http-server.d.ts +196 -0
  54. package/dist/server/http-server.js +295 -0
  55. package/dist/server/http-server.js.map +1 -0
  56. package/dist/server/middlewares/validation.d.ts +12 -0
  57. package/dist/server/middlewares/validation.js +34 -0
  58. package/dist/server/middlewares/validation.js.map +1 -0
  59. package/dist/server/request-processor.d.ts +400 -0
  60. package/dist/server/request-processor.js +652 -0
  61. package/dist/server/request-processor.js.map +1 -0
  62. package/dist/server/request.d.ts +73 -0
  63. package/dist/server/request.js +207 -0
  64. package/dist/server/request.js.map +1 -0
  65. package/dist/server/response.d.ts +69 -0
  66. package/dist/server/response.js +173 -0
  67. package/dist/server/response.js.map +1 -0
  68. package/package.json +46 -0
  69. package/src/config.ts +212 -0
  70. package/src/context/event-context.ts +66 -0
  71. package/src/context/index.ts +32 -0
  72. package/src/context/lithia-context.ts +59 -0
  73. package/src/context/route-context.ts +89 -0
  74. package/src/env.ts +31 -0
  75. package/src/errors.ts +96 -0
  76. package/src/hooks/dependency-hooks.ts +122 -0
  77. package/src/hooks/event-hooks.ts +69 -0
  78. package/src/hooks/index.ts +58 -0
  79. package/src/hooks/route-hooks.ts +177 -0
  80. package/src/lib.ts +27 -0
  81. package/src/lithia.ts +777 -0
  82. package/src/logger.ts +66 -0
  83. package/src/module-loader.ts +45 -0
  84. package/src/server/event-processor.ts +344 -0
  85. package/src/server/http-server.ts +371 -0
  86. package/src/server/middlewares/validation.ts +46 -0
  87. package/src/server/request-processor.ts +860 -0
  88. package/src/server/request.ts +247 -0
  89. package/src/server/response.ts +204 -0
  90. package/tsconfig.build.tsbuildinfo +1 -0
  91. package/tsconfig.json +8 -0
@@ -0,0 +1,447 @@
1
+ /**
2
+ * Core runtime entry for Lithia.
3
+ *
4
+ * This module provides the main `Lithia` class, which orchestrates the entire
5
+ * framework lifecycle including:
6
+ * - Building the project with the native Rust compiler
7
+ * - Loading route and event manifests
8
+ * - Managing the HTTP server lifecycle
9
+ * - Configuration management and hot-reloading
10
+ * - Dependency injection and global middleware
11
+ * - Lifecycle event emission (built, error, config:changed)
12
+ *
13
+ * @module lithia
14
+ */
15
+ import { EventEmitter } from "node:events";
16
+ import { type Event, type Route } from "@lithia-js/native";
17
+ import { type LithiaOptions } from "./config";
18
+ import type { InjectionKey } from "./hooks/dependency-hooks";
19
+ import type { LithiaMiddleware } from "./server/request-processor";
20
+ /**
21
+ * The runtime environment mode.
22
+ *
23
+ * Influences logging verbosity, error output formatting, and features like
24
+ * configuration hot-reloading (enabled only in development).
25
+ */
26
+ export type Environment = "production" | "development";
27
+ /**
28
+ * Options required to create a Lithia instance.
29
+ *
30
+ * These options configure the fundamental paths and environment settings
31
+ * that Lithia needs to build and run your application.
32
+ */
33
+ export interface LithiaCreateOptions {
34
+ /**
35
+ * Runtime environment mode.
36
+ *
37
+ * - `development`: Enables config watching, verbose logging, source maps
38
+ * - `production`: Optimized for performance with minimal logging
39
+ */
40
+ environment: Environment;
41
+ /**
42
+ * Absolute path to the source directory containing application code.
43
+ *
44
+ * @example "./src"
45
+ */
46
+ sourceRoot: string;
47
+ /**
48
+ * Absolute path to the output directory for compiled JavaScript.
49
+ *
50
+ * @example "./dist"
51
+ */
52
+ outRoot: string;
53
+ }
54
+ /**
55
+ * Lithia runtime controller and main framework orchestrator.
56
+ *
57
+ * This is the core class that manages the entire Lithia application lifecycle.
58
+ * It acts as a singleton and coordinates:
59
+ * - Project compilation via the native Rust builder
60
+ * - Route and event manifest loading
61
+ * - HTTP server lifecycle management
62
+ * - Configuration management with hot-reloading in development
63
+ * - Global middleware and dependency injection
64
+ * - Lifecycle event emission and handling
65
+ *
66
+ * @remarks
67
+ * Always use `Lithia.create()` to obtain the singleton instance.
68
+ * Direct instantiation is not supported.
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const lithia = await Lithia.create({
73
+ * environment: 'development',
74
+ * sourceRoot: './src',
75
+ * outRoot: './dist'
76
+ * });
77
+ *
78
+ * lithia.build();
79
+ * await lithia.start();
80
+ * ```
81
+ */
82
+ export declare class Lithia {
83
+ /** Singleton instance of Lithia. */
84
+ private static instance;
85
+ /** Current runtime environment (production or development). */
86
+ private environment;
87
+ /** Absolute path to the source directory. */
88
+ private sourceRoot;
89
+ /** Absolute path to the compiled output directory. */
90
+ private outRoot;
91
+ /** Array of loaded application routes from the manifest. */
92
+ private routes;
93
+ /** Array of loaded Socket.IO events from the manifest. */
94
+ private events;
95
+ /** Current runtime configuration. */
96
+ private config;
97
+ /** Event emitter for lifecycle events (built, error, config:changed). */
98
+ private emitter;
99
+ /** Configuration provider that handles loading and watching. */
100
+ private configProvider;
101
+ /** HTTP server instance (created when start() is called). */
102
+ private httpServer?;
103
+ /** Flag indicating whether the HTTP server is currently running. */
104
+ private serverRunning;
105
+ /** Handle for the configuration file watcher (development only). */
106
+ private configWatchHandle?;
107
+ /**
108
+ * Global middlewares executed for every HTTP request.
109
+ *
110
+ * These run before route-specific handlers and can modify requests,
111
+ * responses, or perform authentication/logging.
112
+ */
113
+ globalMiddlewares: LithiaMiddleware[];
114
+ /**
115
+ * Global dependency injection container.
116
+ *
117
+ * Stores dependencies registered via `provide()` that can be injected
118
+ * into route handlers and middlewares.
119
+ */
120
+ globalDependencies: Map<any, any>;
121
+ /**
122
+ * Gets the current runtime configuration.
123
+ *
124
+ * @returns The current LithiaOptions configuration object
125
+ */
126
+ get options(): LithiaOptions;
127
+ /**
128
+ * Private constructor to enforce singleton pattern.
129
+ *
130
+ * Use `Lithia.create()` instead of instantiating directly.
131
+ *
132
+ * @private
133
+ */
134
+ private constructor();
135
+ /**
136
+ * Creates or returns the global Lithia singleton instance.
137
+ *
138
+ * This is the primary entry point for creating a Lithia application.
139
+ * On first call, it initializes the framework with the provided options,
140
+ * loads configuration, and (in development mode) sets up configuration
141
+ * hot-reloading.
142
+ *
143
+ * Subsequent calls return the same singleton instance.
144
+ *
145
+ * @param options - Configuration for paths and environment
146
+ * @returns The initialized Lithia singleton instance
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * const lithia = await Lithia.create({
151
+ * environment: 'development',
152
+ * sourceRoot: path.resolve('./src'),
153
+ * outRoot: path.resolve('./dist')
154
+ * });
155
+ * ```
156
+ */
157
+ static create(options: LithiaCreateOptions): Promise<Lithia>;
158
+ /**
159
+ * Registers a global middleware to run on every HTTP request.
160
+ *
161
+ * Middlewares are executed in the order they are registered, before
162
+ * route-specific handlers. They can modify the request/response or
163
+ * perform cross-cutting concerns like logging and authentication.
164
+ *
165
+ * @param middleware - The middleware function to register
166
+ * @returns The Lithia instance for method chaining
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * lithia.use(async (req, res, next) => {
171
+ * console.log(`${req.method} ${req.url}`);
172
+ * await next();
173
+ * });
174
+ * ```
175
+ */
176
+ use(middleware: LithiaMiddleware): this;
177
+ /**
178
+ * Registers a global dependency for dependency injection.
179
+ *
180
+ * Registered dependencies can be injected into route handlers and
181
+ * middlewares using the `inject()` hook.
182
+ *
183
+ * @param key - The injection key (use `createInjectionKey<T>()` to create)
184
+ * @param value - The dependency value to provide
185
+ * @returns The Lithia instance for method chaining
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * const dbKey = createInjectionKey<Database>('database');
190
+ * lithia.provide(dbKey, new Database());
191
+ * ```
192
+ */
193
+ provide<T>(key: InjectionKey<T>, value: T): this;
194
+ /**
195
+ * Initializes the Lithia instance with configuration and environment settings.
196
+ *
197
+ * This method:
198
+ * - Sets up the environment, source root, and output root
199
+ * - Loads the initial configuration from lithia.config.ts
200
+ * - Configures the event emitter for lifecycle events
201
+ * - Sets up configuration hot-reloading (development mode only)
202
+ *
203
+ * @param options - Initialization options
204
+ * @private
205
+ */
206
+ private initialize;
207
+ /**
208
+ * Sets up configuration file watching in development mode.
209
+ *
210
+ * Monitors lithia.config.ts for changes and emits `config:changed` events.
211
+ * Logs configuration diffs and warns when changes require a server restart.
212
+ *
213
+ * @private
214
+ */
215
+ private setupConfigWatcher;
216
+ /**
217
+ * Checks if a configuration key change requires a server restart.
218
+ *
219
+ * @param key - The configuration key that changed
220
+ * @returns True if the change requires restarting the server
221
+ * @private
222
+ */
223
+ private configChangeRequiresRestart;
224
+ /**
225
+ * Loads and executes the optional user bootstrap module.
226
+ *
227
+ * Looks for `src/app/_server.ts` (compiled to `dist/app/_server.js`).
228
+ * The bootstrap module should export an async default function that
229
+ * receives the Lithia instance and can register middlewares, providers, etc.
230
+ *
231
+ * @throws {InvalidBootstrapModuleError} If the module has invalid structure
232
+ * @private
233
+ */
234
+ private loadBootstrapModule;
235
+ /**
236
+ * Validates the structure of the bootstrap module.
237
+ *
238
+ * Ensures the module:
239
+ * - Has a default export
240
+ * - Default export is a function
241
+ * - Default export is async
242
+ *
243
+ * @param mod - The loaded module
244
+ * @param filePath - Path to the module file (for error messages)
245
+ * @throws {InvalidBootstrapModuleError} If validation fails
246
+ * @private
247
+ */
248
+ private validateBootstrapModule;
249
+ /**
250
+ * Starts the HTTP server.
251
+ *
252
+ * This method:
253
+ * 1. Loads and executes the optional bootstrap module (_server.ts)
254
+ * 2. Creates the HTTP server with current configuration
255
+ * 3. Starts listening on the configured host and port
256
+ *
257
+ * Safe to call multiple times; subsequent calls are no-ops while the
258
+ * server is running.
259
+ *
260
+ * @throws {InvalidBootstrapModuleError} If bootstrap module is invalid
261
+ * @throws {Error} If server fails to start
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * await lithia.start();
266
+ * // Server is now listening on configured port
267
+ * ```
268
+ */
269
+ start(): Promise<void>;
270
+ /**
271
+ * Stops the HTTP server.
272
+ *
273
+ * Gracefully shuts down the server and closes all active connections.
274
+ * No-op if the server isn't currently running.
275
+ *
276
+ * @example
277
+ * ```typescript
278
+ * await lithia.stop();
279
+ * // Server is now stopped
280
+ * ```
281
+ */
282
+ stop(): Promise<void>;
283
+ /**
284
+ * Executes a function within the Lithia context.
285
+ *
286
+ * Provides access to the global dependency container during execution.
287
+ * Used internally by the request processor to make dependencies available
288
+ * to route handlers and middlewares.
289
+ *
290
+ * @param fn - Async function to execute within the context
291
+ * @returns The result of the function execution
292
+ * @template T - The return type of the function
293
+ *
294
+ * @example
295
+ * ```typescript
296
+ * const result = await lithia.runWithContext(async () => {
297
+ * const db = inject(dbKey);
298
+ * return db.query('SELECT * FROM users');
299
+ * });
300
+ * ```
301
+ */
302
+ runWithContext<T>(fn: () => Promise<T>): Promise<T>;
303
+ /**
304
+ * Gets the current runtime environment.
305
+ *
306
+ * @returns The environment mode ('production' or 'development')
307
+ */
308
+ getEnvironment(): Environment;
309
+ /**
310
+ * Gets the currently loaded routes from the manifest.
311
+ *
312
+ * Routes are loaded after a successful build via the `loadRoutes()` method.
313
+ *
314
+ * @returns Array of route definitions
315
+ */
316
+ getRoutes(): Route[];
317
+ /**
318
+ * Gets the currently loaded Socket.IO events from the manifest.
319
+ *
320
+ * Events are loaded after a successful build via the `loadEvents()` method.
321
+ *
322
+ * @returns Array of event definitions
323
+ */
324
+ getEvents(): Event[];
325
+ /**
326
+ * Gets the current runtime configuration.
327
+ *
328
+ * @returns The current LithiaOptions configuration object
329
+ */
330
+ getConfig(): LithiaOptions;
331
+ /**
332
+ * Configures internal event handlers for the lifecycle emitter.
333
+ *
334
+ * Sets up handlers for:
335
+ * - `built` event: Triggered after successful compilation, loads routes and events
336
+ * - `error` event: Logs errors with appropriate severity and exits on fatal errors
337
+ *
338
+ * @private
339
+ */
340
+ private configureEventEmitter;
341
+ /**
342
+ * Compiles the project using the native Rust compiler.
343
+ *
344
+ * This performs a synchronous build that:
345
+ * - Scans the source directory for routes and events
346
+ * - Compiles TypeScript to JavaScript
347
+ * - Generates route and event manifests (routes.json, events.json)
348
+ *
349
+ * On success, emits the `built` event with build duration in milliseconds.
350
+ * On failure, emits the `error` event.
351
+ *
352
+ * @example
353
+ * ```typescript
354
+ * lithia.on('built', () => {
355
+ * console.log('Build complete!');
356
+ * });
357
+ * lithia.build();
358
+ * ```
359
+ */
360
+ build(): void;
361
+ /**
362
+ * Loads and validates a JSON manifest file.
363
+ *
364
+ * @param fileName - Name of the manifest file (e.g., 'routes.json')
365
+ * @returns The parsed manifest object
366
+ * @throws {ManifestLoadError} If the file cannot be read or parsed
367
+ * @throws {SchemaVersionMismatchError} If the manifest version doesn't match
368
+ * @private
369
+ */
370
+ private loadManifest;
371
+ /**
372
+ * Loads and validates the routes manifest generated by the compiler.
373
+ *
374
+ * Reads `routes.json` from the output directory and populates the
375
+ * internal routes array. This is automatically called after a successful
376
+ * build (via the `built` event handler).
377
+ *
378
+ * On error, emits an `error` event and leaves routes unchanged.
379
+ */
380
+ loadRoutes(): void;
381
+ /**
382
+ * Loads and validates the events manifest generated by the compiler.
383
+ *
384
+ * Reads `events.json` from the output directory and populates the
385
+ * internal events array. This is automatically called after a successful
386
+ * build (via the `built` event handler).
387
+ *
388
+ * On error, emits an `error` event and leaves events unchanged.
389
+ */
390
+ loadEvents(): void;
391
+ /**
392
+ * Gets the internal EventEmitter instance.
393
+ *
394
+ * The event emitter is used for lifecycle events like:
395
+ * - `built`: Emitted after successful compilation
396
+ * - `error`: Emitted when errors occur
397
+ * - `config:changed`: Emitted when configuration is updated (dev mode)
398
+ *
399
+ * @returns The internal EventEmitter instance
400
+ */
401
+ getEventEmitter(): EventEmitter<any>;
402
+ /**
403
+ * Emits a lifecycle event.
404
+ *
405
+ * @param event - The event name to emit
406
+ * @param payload - Optional payload data for the event
407
+ * @returns True if the event had listeners, false otherwise
408
+ *
409
+ * @example
410
+ * ```typescript
411
+ * lithia.emit('custom:event', { data: 'value' });
412
+ * ```
413
+ */
414
+ emit(event: string, payload?: any): boolean;
415
+ /**
416
+ * Registers a listener for a lifecycle event.
417
+ *
418
+ * @param event - The event name to listen for
419
+ * @param listener - Callback function to execute when the event is emitted
420
+ *
421
+ * @example
422
+ * ```typescript
423
+ * lithia.on('built', (durationMs) => {
424
+ * console.log(`Build took ${durationMs}ms`);
425
+ * });
426
+ *
427
+ * lithia.on('error', (error) => {
428
+ * console.error('An error occurred:', error);
429
+ * });
430
+ * ```
431
+ */
432
+ on(event: string, listener: (...args: any[]) => void): void;
433
+ /**
434
+ * Cleans up resources and removes all event listeners.
435
+ *
436
+ * This method should be called when shutting down the application to:
437
+ * - Close the configuration file watcher
438
+ * - Remove all event listeners to prevent memory leaks
439
+ *
440
+ * @example
441
+ * ```typescript
442
+ * await lithia.stop();
443
+ * lithia.close();
444
+ * ```
445
+ */
446
+ close(): void;
447
+ }