@cepseudo/engine 1.0.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 (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +209 -0
  3. package/dist/component_types.d.ts +92 -0
  4. package/dist/component_types.d.ts.map +1 -0
  5. package/dist/component_types.js +93 -0
  6. package/dist/component_types.js.map +1 -0
  7. package/dist/digital_twin_engine.d.ts +390 -0
  8. package/dist/digital_twin_engine.d.ts.map +1 -0
  9. package/dist/digital_twin_engine.js +1200 -0
  10. package/dist/digital_twin_engine.js.map +1 -0
  11. package/dist/endpoints.d.ts +45 -0
  12. package/dist/endpoints.d.ts.map +1 -0
  13. package/dist/endpoints.js +87 -0
  14. package/dist/endpoints.js.map +1 -0
  15. package/dist/error_handler.d.ts +20 -0
  16. package/dist/error_handler.d.ts.map +1 -0
  17. package/dist/error_handler.js +68 -0
  18. package/dist/error_handler.js.map +1 -0
  19. package/dist/global_assets_handler.d.ts +63 -0
  20. package/dist/global_assets_handler.d.ts.map +1 -0
  21. package/dist/global_assets_handler.js +127 -0
  22. package/dist/global_assets_handler.js.map +1 -0
  23. package/dist/graceful_shutdown.d.ts +44 -0
  24. package/dist/graceful_shutdown.d.ts.map +1 -0
  25. package/dist/graceful_shutdown.js +79 -0
  26. package/dist/graceful_shutdown.js.map +1 -0
  27. package/dist/health.d.ts +112 -0
  28. package/dist/health.d.ts.map +1 -0
  29. package/dist/health.js +190 -0
  30. package/dist/health.js.map +1 -0
  31. package/dist/index.d.ts +19 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +25 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/initializer.d.ts +62 -0
  36. package/dist/initializer.d.ts.map +1 -0
  37. package/dist/initializer.js +110 -0
  38. package/dist/initializer.js.map +1 -0
  39. package/dist/loader/component_loader.d.ts +133 -0
  40. package/dist/loader/component_loader.d.ts.map +1 -0
  41. package/dist/loader/component_loader.js +340 -0
  42. package/dist/loader/component_loader.js.map +1 -0
  43. package/dist/openapi/generator.d.ts +93 -0
  44. package/dist/openapi/generator.d.ts.map +1 -0
  45. package/dist/openapi/generator.js +293 -0
  46. package/dist/openapi/generator.js.map +1 -0
  47. package/dist/queue_manager.d.ts +87 -0
  48. package/dist/queue_manager.d.ts.map +1 -0
  49. package/dist/queue_manager.js +196 -0
  50. package/dist/queue_manager.js.map +1 -0
  51. package/dist/scheduler.d.ts +29 -0
  52. package/dist/scheduler.d.ts.map +1 -0
  53. package/dist/scheduler.js +375 -0
  54. package/dist/scheduler.js.map +1 -0
  55. package/package.json +78 -0
@@ -0,0 +1,390 @@
1
+ import type { Collector, Harvester, Handler, CustomTableManager } from '@cepseudo/components';
2
+ import type { AssetsManager } from '@cepseudo/assets';
3
+ import type { StorageService } from '@cepseudo/storage';
4
+ import type { DatabaseAdapter } from '@cepseudo/database';
5
+ import type { Router as ExpressRouter } from 'ultimate-express';
6
+ import type { ConnectionOptions } from 'bullmq';
7
+ import { type AnyComponent, type LoadedComponents } from './component_types.js';
8
+ import { LogLevel } from '@cepseudo/shared';
9
+ import type { QueueConfig } from './queue_manager.js';
10
+ import { type HealthCheckFn } from './health.js';
11
+ /**
12
+ * Result of component validation
13
+ */
14
+ export interface ComponentValidationResult {
15
+ /** Component name */
16
+ name: string;
17
+ /** Component type */
18
+ type: 'collector' | 'harvester' | 'handler' | 'assets_manager' | 'custom_table_manager';
19
+ /** Validation status */
20
+ valid: boolean;
21
+ /** Validation errors if any */
22
+ errors: string[];
23
+ /** Validation warnings if any */
24
+ warnings: string[];
25
+ }
26
+ /**
27
+ * Overall validation result
28
+ */
29
+ export interface ValidationResult {
30
+ /** Overall validation status */
31
+ valid: boolean;
32
+ /** Individual component results */
33
+ components: ComponentValidationResult[];
34
+ /** Engine-level errors */
35
+ engineErrors: string[];
36
+ /** Summary statistics */
37
+ summary: {
38
+ total: number;
39
+ valid: number;
40
+ invalid: number;
41
+ warnings: number;
42
+ };
43
+ }
44
+ /**
45
+ * Configuration options for the Digital Twin Engine
46
+ *
47
+ * @interface EngineOptions
48
+ * @example
49
+ * ```typescript
50
+ * const options: EngineOptions = {
51
+ * storage: storageService,
52
+ * database: databaseAdapter,
53
+ * collectors: [myCollector],
54
+ * harvesters: [myHarvester],
55
+ * handlers: [myHandler],
56
+ * server: { port: 3000, host: 'localhost' },
57
+ * queues: {
58
+ * multiQueue: true,
59
+ * workers: { collectors: 2, harvesters: 1 }
60
+ * }
61
+ * }
62
+ * ```
63
+ */
64
+ export interface EngineOptions {
65
+ /** Array of data collectors to register with the engine */
66
+ collectors?: Collector[];
67
+ /** Array of data harvesters to register with the engine */
68
+ harvesters?: Harvester[];
69
+ /** Array of request handlers to register with the engine */
70
+ handlers?: Handler[];
71
+ /** Array of assets managers to register with the engine */
72
+ assetsManagers?: AssetsManager[];
73
+ /** Array of custom table managers to register with the engine */
74
+ customTableManagers?: CustomTableManager[];
75
+ /** Storage service instance for persisting data (required) */
76
+ storage: StorageService;
77
+ /** Database adapter instance for data operations (required) */
78
+ database: DatabaseAdapter;
79
+ /** Redis connection options for queue management */
80
+ redis?: ConnectionOptions;
81
+ /** Queue configuration options */
82
+ queues?: {
83
+ /** Enable multi-queue mode (default: true) */
84
+ multiQueue?: boolean;
85
+ /** Worker configuration for different component types */
86
+ workers?: {
87
+ /** Number of collector workers (default: 1) */
88
+ collectors?: number;
89
+ /** Number of harvester workers (default: 1) */
90
+ harvesters?: number;
91
+ };
92
+ /** Additional queue configuration options */
93
+ options?: QueueConfig['queueOptions'];
94
+ };
95
+ /** HTTP server configuration */
96
+ server?: {
97
+ /** Server port (default: 3000) */
98
+ port: number;
99
+ /** Server host (default: '0.0.0.0') */
100
+ host?: string;
101
+ };
102
+ /** Logging configuration */
103
+ logging?: {
104
+ /** Log level (default: LogLevel.INFO) */
105
+ level: LogLevel;
106
+ /** Log format (default: 'text') */
107
+ format?: 'json' | 'text';
108
+ };
109
+ /** Dry run mode - validate configuration without persisting data (default: false) */
110
+ dryRun?: boolean;
111
+ /**
112
+ * Enable automatic schema migration for existing tables (default: true)
113
+ *
114
+ * When enabled, the engine will automatically add missing columns with safe defaults
115
+ * to existing tables at startup. Only safe operations are performed:
116
+ * - Adding columns with DEFAULT values
117
+ * - Adding nullable columns
118
+ * - Adding indexes
119
+ *
120
+ * Set to false to require manual migrations via SQL scripts.
121
+ */
122
+ autoMigration?: boolean;
123
+ }
124
+ /**
125
+ * Digital Twin Engine - Core orchestrator for collectors, harvesters, and handlers
126
+ *
127
+ * The engine manages the lifecycle of all components, sets up queues for processing,
128
+ * exposes HTTP endpoints, and handles the overall coordination of the digital twin system.
129
+ *
130
+ * @class DigitalTwinEngine
131
+ * @example
132
+ * ```TypeScript
133
+ * import { DigitalTwinEngine } from './digital_twin_engine.js'
134
+ * import { StorageServiceFactory } from '../storage/storage_factory.js'
135
+ * import { KnexDatabaseAdapter } from '../database/adapters/knex_database_adapter.js'
136
+ *
137
+ * const storage = StorageServiceFactory.create()
138
+ * const database = new KnexDatabaseAdapter({ client: 'sqlite3', connection: ':memory:' }, storage)
139
+ *
140
+ * const engine = new DigitalTwinEngine({
141
+ * storage,
142
+ * database,
143
+ * collectors: [myCollector],
144
+ * server: { port: 3000 }
145
+ * })
146
+ *
147
+ * await engine.start()
148
+ * ```
149
+ */
150
+ export declare class DigitalTwinEngine {
151
+ #private;
152
+ /**
153
+ * Creates a new Digital Twin Engine instance
154
+ *
155
+ * @param {EngineOptions} options - Configuration options for the engine
156
+ * @throws {Error} If required options (storage, database) are missing
157
+ *
158
+ * @example
159
+ * ```TypeScript
160
+ * const engine = new DigitalTwinEngine({
161
+ * storage: myStorageService,
162
+ * database: myDatabaseAdapter,
163
+ * collectors: [collector1, collector2],
164
+ * server: { port: 4000, host: 'localhost' }
165
+ * })
166
+ * ```
167
+ */
168
+ constructor(options: EngineOptions);
169
+ /**
170
+ * Starts the Digital Twin Engine
171
+ *
172
+ * This method:
173
+ * 1. Initializes all registered components (collectors, harvesters, handlers)
174
+ * 2. Set up HTTP endpoints for component access
175
+ * 3. Configures and starts background job queues
176
+ * 4. Starts the HTTP server
177
+ * 5. Exposes queue monitoring endpoints
178
+ *
179
+ * @async
180
+ * @returns {Promise<void>}
181
+ *
182
+ * @example
183
+ * ```TypeScript
184
+ * await engine.start()
185
+ * console.log('Engine is running!')
186
+ * ```
187
+ */
188
+ start(): Promise<void>;
189
+ /**
190
+ * Get the server port
191
+ *
192
+ * @returns {number | undefined} The server port or undefined if not started
193
+ *
194
+ * @example
195
+ * ```TypeScript
196
+ * const port = engine.getPort()
197
+ * console.log(`Server running on port ${port}`)
198
+ * ```
199
+ */
200
+ getPort(): number | undefined;
201
+ /**
202
+ * Returns the internal Express Router.
203
+ * Used by optional plugin packages to register additional routes.
204
+ */
205
+ getRouter(): ExpressRouter;
206
+ /**
207
+ * Returns the DatabaseAdapter instance.
208
+ * Used by optional plugin packages for their own persistence needs.
209
+ */
210
+ getDatabase(): DatabaseAdapter;
211
+ /**
212
+ * Returns the Redis connection configuration extracted from engine options.
213
+ * Falls back to localhost:6379 when no Redis config was provided.
214
+ */
215
+ getRedisConfig(): {
216
+ host: string;
217
+ port: number;
218
+ password?: string;
219
+ };
220
+ /**
221
+ * Returns a flat list of all components registered with the engine.
222
+ * Used by optional plugin packages to inspect component capabilities.
223
+ */
224
+ getAllComponents(): AnyComponent[];
225
+ /**
226
+ * Registers a single component with automatic type detection.
227
+ *
228
+ * The engine automatically detects the component type based on its class
229
+ * and adds it to the appropriate internal collection.
230
+ *
231
+ * @param component - Component instance to register
232
+ * @returns The engine instance for method chaining
233
+ * @throws Error if component type cannot be determined or is already registered
234
+ *
235
+ * @example
236
+ * ```typescript
237
+ * const engine = new DigitalTwinEngine({ storage, database })
238
+ *
239
+ * engine
240
+ * .register(new WeatherCollector())
241
+ * .register(new TrafficAnalysisHarvester())
242
+ * .register(new ApiHandler())
243
+ * .register(new GLTFAssetsManager())
244
+ *
245
+ * await engine.start()
246
+ * ```
247
+ */
248
+ register(component: AnyComponent): this;
249
+ /**
250
+ * Registers multiple components at once with automatic type detection.
251
+ *
252
+ * Useful for registering all components from a module or when loading
253
+ * components dynamically.
254
+ *
255
+ * @param components - Array of component instances to register
256
+ * @returns The engine instance for method chaining
257
+ * @throws Error if any component type cannot be determined or is duplicate
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const engine = new DigitalTwinEngine({ storage, database })
262
+ *
263
+ * engine.registerAll([
264
+ * new WeatherCollector(),
265
+ * new TrafficCollector(),
266
+ * new AnalysisHarvester(),
267
+ * new ApiHandler()
268
+ * ])
269
+ *
270
+ * await engine.start()
271
+ * ```
272
+ */
273
+ registerAll(components: AnyComponent[]): this;
274
+ /**
275
+ * Registers components with explicit type specification.
276
+ *
277
+ * Provides full type safety at compile time. Use this method when you
278
+ * have pre-sorted components from auto-discovery or want explicit control.
279
+ *
280
+ * @param components - Object with typed component arrays
281
+ * @returns The engine instance for method chaining
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * const loaded = await loadComponents('./src/components')
286
+ *
287
+ * engine.registerComponents({
288
+ * collectors: loaded.collectors,
289
+ * harvesters: loaded.harvesters,
290
+ * handlers: loaded.handlers,
291
+ * assetsManagers: loaded.assetsManagers,
292
+ * customTableManagers: loaded.customTableManagers
293
+ * })
294
+ * ```
295
+ */
296
+ registerComponents(components: Partial<LoadedComponents>): this;
297
+ /**
298
+ * Configure the shutdown timeout (in ms)
299
+ * @param timeout Timeout in milliseconds (default: 30000)
300
+ */
301
+ setShutdownTimeout(timeout: number): void;
302
+ /**
303
+ * Check if the engine is currently shutting down
304
+ * @returns true if shutdown is in progress
305
+ */
306
+ isShuttingDown(): boolean;
307
+ /**
308
+ * Register a custom health check
309
+ * @param name Unique name for the check
310
+ * @param checkFn Function that performs the check
311
+ *
312
+ * @example
313
+ * ```typescript
314
+ * engine.registerHealthCheck('external-api', async () => {
315
+ * try {
316
+ * const res = await fetch('https://api.example.com/health')
317
+ * return { status: res.ok ? 'up' : 'down' }
318
+ * } catch (error) {
319
+ * return { status: 'down', error: error.message }
320
+ * }
321
+ * })
322
+ * ```
323
+ */
324
+ registerHealthCheck(name: string, checkFn: HealthCheckFn): void;
325
+ /**
326
+ * Remove a custom health check
327
+ * @param name Name of the check to remove
328
+ * @returns true if the check was removed, false if it didn't exist
329
+ */
330
+ removeHealthCheck(name: string): boolean;
331
+ /**
332
+ * Get list of registered health check names
333
+ */
334
+ getHealthCheckNames(): string[];
335
+ /**
336
+ * Stops the Digital Twin Engine with graceful shutdown
337
+ *
338
+ * This method:
339
+ * 1. Prevents new work from being accepted
340
+ * 2. Removes all event listeners
341
+ * 3. Closes HTTP server
342
+ * 4. Drains queues and waits for active jobs
343
+ * 5. Closes all queue workers
344
+ * 6. Stops upload processor
345
+ * 7. Closes queue manager
346
+ * 8. Closes database connections
347
+ *
348
+ * @async
349
+ * @returns {Promise<void>}
350
+ *
351
+ * @example
352
+ * ```TypeScript
353
+ * await engine.stop()
354
+ * console.log('Engine stopped gracefully')
355
+ * ```
356
+ */
357
+ stop(): Promise<void>;
358
+ /**
359
+ * Validate the engine configuration and all components
360
+ *
361
+ * This method checks that all components are properly configured and can be initialized
362
+ * without actually creating tables or starting the server.
363
+ *
364
+ * @returns {Promise<ValidationResult>} Comprehensive validation results
365
+ *
366
+ * @example
367
+ * ```typescript
368
+ * const result = await engine.validateConfiguration()
369
+ * if (!result.valid) {
370
+ * console.error('Validation errors:', result.engineErrors)
371
+ * }
372
+ * ```
373
+ */
374
+ validateConfiguration(): Promise<ValidationResult>;
375
+ /**
376
+ * Test all components by running their core methods without persistence
377
+ *
378
+ * @returns {Promise<ComponentValidationResult[]>} Test results for each component
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * const results = await engine.testComponents()
383
+ * results.forEach(result => {
384
+ * console.log(`${result.name}: ${result.valid ? '✅' : '❌'}`)
385
+ * })
386
+ * ```
387
+ */
388
+ testComponents(): Promise<ComponentValidationResult[]>;
389
+ }
390
+ //# sourceMappingURL=digital_twin_engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digital_twin_engine.d.ts","sourceRoot":"","sources":["../src/digital_twin_engine.ts"],"names":[],"mappings":"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"}