@devilsdev/rag-pipeline-utils 2.2.0 → 2.3.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 (46) hide show
  1. package/README.md +323 -722
  2. package/contracts/contract-schema.json +189 -0
  3. package/contracts/reranker-contract.json +69 -0
  4. package/dist/index.cjs +19 -0
  5. package/dist/index.mjs +15 -1
  6. package/package.json +4 -2
  7. package/src/cli/commands/wizard.js +627 -0
  8. package/src/cli/input-sanitization-middleware.js +356 -0
  9. package/src/cli/templates/development.template.json +64 -0
  10. package/src/cli/templates/minimal.template.json +33 -0
  11. package/src/cli/templates/production.template.json +104 -0
  12. package/src/cli/templates/testing.template.json +45 -0
  13. package/src/config/connection-pool-config.json +259 -0
  14. package/src/config/memory-optimization.js +414 -0
  15. package/src/config/redaction-patterns.json +150 -0
  16. package/src/config/sanitization-rules.json +323 -0
  17. package/src/core/performance/streaming-safeguards.js +10 -1
  18. package/src/core/plugin-registry.js +275 -0
  19. package/src/dag/core/error-context.js +391 -0
  20. package/src/dag/core/execution-scheduler.js +350 -0
  21. package/src/dag/core/topology-validation.js +415 -0
  22. package/src/dag/dag-engine.js +26 -424
  23. package/src/dev/README.md +126 -0
  24. package/src/dev/dev-server.js +356 -0
  25. package/src/dev/examples/hot-reload-usage.js +355 -0
  26. package/src/dev/hot-reload.js +807 -0
  27. package/src/enterprise/sso-integration.js +184 -15
  28. package/src/index.js +19 -0
  29. package/src/observability/event-logger.js +62 -2
  30. package/src/plugins/optimized-openai-embedder.js +169 -0
  31. package/src/reranker/llm-reranker.js +30 -4
  32. package/src/security/jwt-config.js +431 -0
  33. package/src/security/jwt-validator.js +701 -0
  34. package/src/utils/api-client-pool-integration.js +436 -0
  35. package/src/utils/batch-processor.js +710 -0
  36. package/src/utils/connection-pool.js +605 -0
  37. package/src/utils/contract-validator.js +460 -0
  38. package/src/utils/error-formatter.js +603 -0
  39. package/src/utils/examples/error-formatter-usage.js +351 -0
  40. package/src/utils/input-sanitizer.js +967 -0
  41. package/src/utils/memory-monitor.js +800 -0
  42. package/src/utils/rate-limiter.js +244 -0
  43. package/src/utils/secure-logger-config.js +352 -0
  44. package/src/utils/secure-logger.js +576 -0
  45. package/src/utils/secure-logging.js +338 -0
  46. package/src/utils/structured-logger.js +32 -5
@@ -0,0 +1,356 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Development Server with Hot Reload Support
5
+ *
6
+ * Provides a development server with integrated hot reloading
7
+ * for rapid plugin and configuration development.
8
+ *
9
+ * Features:
10
+ * - Automatic hot reloading of plugins and configuration
11
+ * - Live feedback on reload status
12
+ * - Error notifications
13
+ * - Statistics dashboard
14
+ * - WebSocket support for real-time updates (optional)
15
+ *
16
+ * @module dev/dev-server
17
+ * @since 2.4.0
18
+ */
19
+
20
+ const { EventEmitter } = require('events');
21
+ const { createHotReloadManager } = require('./hot-reload');
22
+ const logger = require('../utils/logger');
23
+
24
+ /**
25
+ * Development Server
26
+ *
27
+ * Integrates hot reloading with a development workflow
28
+ */
29
+ class DevServer extends EventEmitter {
30
+ constructor(options = {}) {
31
+ super();
32
+
33
+ this.options = {
34
+ port: options.port || 3000,
35
+ host: options.host || 'localhost',
36
+ watchPaths: options.watchPaths || ['./src/plugins', './src/mocks'],
37
+ configPath: options.configPath || '.ragrc.json',
38
+ verbose: options.verbose !== false,
39
+ autoReload: options.autoReload !== false,
40
+ notifyOnReload: options.notifyOnReload !== false,
41
+ pluginRegistry: options.pluginRegistry || null,
42
+ pipeline: options.pipeline || null,
43
+ ...options,
44
+ };
45
+
46
+ // Create hot reload manager
47
+ this.hotReload = createHotReloadManager({
48
+ enabled: this.options.autoReload,
49
+ watchPaths: this.options.watchPaths,
50
+ configPath: this.options.configPath,
51
+ verbose: this.options.verbose,
52
+ pluginRegistry: this.options.pluginRegistry,
53
+ preserveState: true,
54
+ });
55
+
56
+ this.isRunning = false;
57
+ this.startTime = null;
58
+
59
+ // Setup hot reload event handlers
60
+ this._setupHotReloadHandlers();
61
+ }
62
+
63
+ /**
64
+ * Setup hot reload event handlers
65
+ *
66
+ * @private
67
+ */
68
+ _setupHotReloadHandlers() {
69
+ // Plugin reloaded
70
+ this.hotReload.on('plugin:reloaded', ({ path, duration }) => {
71
+ this._log(`✓ Plugin reloaded: ${path} (${duration}ms)`, 'success');
72
+ this.emit('plugin:reloaded', { path, duration });
73
+
74
+ if (this.options.notifyOnReload) {
75
+ this._notify(`Plugin reloaded: ${path}`, 'success');
76
+ }
77
+ });
78
+
79
+ // Plugin reload failed
80
+ this.hotReload.on('plugin:reload-failed', ({ path, error }) => {
81
+ this._log(`✗ Plugin reload failed: ${path} - ${error}`, 'error');
82
+ this.emit('plugin:reload-failed', { path, error });
83
+
84
+ if (this.options.notifyOnReload) {
85
+ this._notify(`Plugin reload failed: ${path}`, 'error');
86
+ }
87
+ });
88
+
89
+ // Config reloaded
90
+ this.hotReload.on('config:reloaded', ({ path, duration }) => {
91
+ this._log(`✓ Configuration reloaded: ${path} (${duration}ms)`, 'success');
92
+ this.emit('config:reloaded', { path, duration });
93
+
94
+ if (this.options.notifyOnReload) {
95
+ this._notify(`Configuration reloaded`, 'success');
96
+ }
97
+
98
+ // Reinitialize pipeline if provided
99
+ if (this.options.pipeline && this.options.pipeline.reinitialize) {
100
+ this.options.pipeline.reinitialize();
101
+ }
102
+ });
103
+
104
+ // Config reload failed
105
+ this.hotReload.on('config:reload-failed', ({ path, error }) => {
106
+ this._log(`✗ Configuration reload failed: ${path} - ${error}`, 'error');
107
+ this.emit('config:reload-failed', { path, error });
108
+
109
+ if (this.options.notifyOnReload) {
110
+ this._notify(`Configuration reload failed`, 'error');
111
+ }
112
+ });
113
+
114
+ // Plugin added
115
+ this.hotReload.on('plugin:added', ({ path }) => {
116
+ this._log(`+ New plugin detected: ${path}`, 'info');
117
+ this.emit('plugin:added', { path });
118
+ });
119
+
120
+ // Plugin removed
121
+ this.hotReload.on('plugin:removed', ({ path }) => {
122
+ this._log(`- Plugin removed: ${path}`, 'info');
123
+ this.emit('plugin:removed', { path });
124
+ });
125
+
126
+ // Error
127
+ this.hotReload.on('error', ({ message, error }) => {
128
+ this._log(`ERROR: ${message} - ${error}`, 'error');
129
+ this.emit('error', { message, error });
130
+ });
131
+ }
132
+
133
+ /**
134
+ * Start the development server
135
+ *
136
+ * @returns {Promise<void>}
137
+ */
138
+ async start() {
139
+ if (this.isRunning) {
140
+ this._log('Development server is already running', 'warn');
141
+ return;
142
+ }
143
+
144
+ this._log('Starting development server...', 'info');
145
+ this.startTime = Date.now();
146
+
147
+ // Start hot reload
148
+ await this.hotReload.start();
149
+
150
+ this.isRunning = true;
151
+
152
+ this._log(
153
+ `Development server started on ${this.options.host}:${this.options.port}`,
154
+ 'success',
155
+ );
156
+ this._log(`Watching: ${this.options.watchPaths.join(', ')}`, 'info');
157
+ this._log(
158
+ 'Hot reload enabled - changes will be applied automatically',
159
+ 'info',
160
+ );
161
+ this._log('Press Ctrl+C to stop', 'info');
162
+
163
+ this.emit('started');
164
+ }
165
+
166
+ /**
167
+ * Stop the development server
168
+ *
169
+ * @returns {Promise<void>}
170
+ */
171
+ async stop() {
172
+ if (!this.isRunning) {
173
+ return;
174
+ }
175
+
176
+ this._log('Stopping development server...', 'info');
177
+
178
+ // Stop hot reload
179
+ await this.hotReload.stop();
180
+
181
+ this.isRunning = false;
182
+
183
+ const uptime = this.startTime ? Date.now() - this.startTime : 0;
184
+ this._log(
185
+ `Development server stopped (uptime: ${this._formatDuration(uptime)})`,
186
+ 'info',
187
+ );
188
+
189
+ this.emit('stopped');
190
+ }
191
+
192
+ /**
193
+ * Get server status
194
+ *
195
+ * @returns {object} Server status
196
+ */
197
+ getStatus() {
198
+ const stats = this.hotReload.getStats();
199
+ const uptime = this.startTime ? Date.now() - this.startTime : 0;
200
+
201
+ return {
202
+ isRunning: this.isRunning,
203
+ uptime,
204
+ host: this.options.host,
205
+ port: this.options.port,
206
+ watchPaths: this.options.watchPaths,
207
+ configPath: this.options.configPath,
208
+ hotReload: {
209
+ enabled: this.options.autoReload,
210
+ stats,
211
+ },
212
+ };
213
+ }
214
+
215
+ /**
216
+ * Get statistics dashboard
217
+ *
218
+ * @returns {string} Formatted statistics
219
+ */
220
+ getStatistics() {
221
+ const stats = this.hotReload.getStats();
222
+ const uptime = this.startTime ? Date.now() - this.startTime : 0;
223
+
224
+ return `
225
+ ╔════════════════════════════════════════════════════════════════╗
226
+ ║ Development Server Statistics ║
227
+ ╠════════════════════════════════════════════════════════════════╣
228
+ ║ Status: ${this.isRunning ? 'Running' : 'Stopped'} ║
229
+ ║ Uptime: ${this._formatDuration(uptime).padEnd(39)}║
230
+ ║ ║
231
+ ║ Hot Reload: ║
232
+ ║ Total Reloads: ${String(stats.totalReloads).padEnd(39)}║
233
+ ║ Successful: ${String(stats.successfulReloads).padEnd(39)}║
234
+ ║ Failed: ${String(stats.failedReloads).padEnd(39)}║
235
+ ║ Plugin Reloads: ${String(stats.pluginReloads).padEnd(39)}║
236
+ ║ Config Reloads: ${String(stats.configReloads).padEnd(39)}║
237
+ ║ Avg Reload Time: ${String(Math.round(stats.averageReloadTime) + 'ms').padEnd(39)}║
238
+ ║ ║
239
+ ║ Watching: ║
240
+ ${this.options.watchPaths.map((p) => `║ - ${p.padEnd(56)}║`).join('\n')}
241
+ ╚════════════════════════════════════════════════════════════════╝
242
+ `.trim();
243
+ }
244
+
245
+ /**
246
+ * Manually trigger a reload
247
+ *
248
+ * @param {string} filePath - File path to reload
249
+ * @param {string} type - Type ('plugin' or 'config')
250
+ * @returns {Promise<void>}
251
+ */
252
+ async triggerReload(filePath, type = 'plugin') {
253
+ this._log(`Manually triggering reload: ${filePath}`, 'info');
254
+ await this.hotReload.triggerReload(filePath, type);
255
+ }
256
+
257
+ /**
258
+ * Register a lifecycle hook
259
+ *
260
+ * @param {string} hookName - Hook name
261
+ * @param {Function} callback - Hook callback
262
+ */
263
+ registerHook(hookName, callback) {
264
+ this.hotReload.registerHook(hookName, callback);
265
+ }
266
+
267
+ /**
268
+ * Unregister a lifecycle hook
269
+ *
270
+ * @param {string} hookName - Hook name
271
+ * @param {Function} callback - Hook callback
272
+ */
273
+ unregisterHook(hookName, callback) {
274
+ this.hotReload.unregisterHook(hookName, callback);
275
+ }
276
+
277
+ /**
278
+ * Log message
279
+ *
280
+ * @private
281
+ * @param {string} message - Log message
282
+ * @param {string} level - Log level
283
+ */
284
+ _log(message, level = 'info') {
285
+ if (!this.options.verbose && level === 'info') {
286
+ return;
287
+ }
288
+
289
+ const prefix = '[DevServer]';
290
+
291
+ switch (level) {
292
+ case 'success':
293
+ console.log(`${prefix} ✓ ${message}`);
294
+ break;
295
+ case 'error':
296
+ console.error(`${prefix} ✗ ${message}`);
297
+ break;
298
+ case 'warn':
299
+ console.warn(`${prefix} ⚠ ${message}`);
300
+ break;
301
+ case 'info':
302
+ default:
303
+ console.log(`${prefix} ${message}`);
304
+ break;
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Send notification
310
+ *
311
+ * @private
312
+ * @param {string} message - Notification message
313
+ * @param {string} type - Notification type
314
+ */
315
+ _notify(message, type = 'info') {
316
+ // In a real implementation, this could send desktop notifications
317
+ // or WebSocket messages to connected clients
318
+ this.emit('notification', { message, type, timestamp: new Date() });
319
+ }
320
+
321
+ /**
322
+ * Format duration
323
+ *
324
+ * @private
325
+ * @param {number} ms - Duration in milliseconds
326
+ * @returns {string} Formatted duration
327
+ */
328
+ _formatDuration(ms) {
329
+ const seconds = Math.floor(ms / 1000);
330
+ const minutes = Math.floor(seconds / 60);
331
+ const hours = Math.floor(minutes / 60);
332
+
333
+ if (hours > 0) {
334
+ return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
335
+ } else if (minutes > 0) {
336
+ return `${minutes}m ${seconds % 60}s`;
337
+ } else {
338
+ return `${seconds}s`;
339
+ }
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Create development server
345
+ *
346
+ * @param {object} options - Server options
347
+ * @returns {DevServer} Development server instance
348
+ */
349
+ function createDevServer(options = {}) {
350
+ return new DevServer(options);
351
+ }
352
+
353
+ module.exports = {
354
+ DevServer,
355
+ createDevServer,
356
+ };
@@ -0,0 +1,355 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Hot Reload Usage Examples
5
+ *
6
+ * This file demonstrates various ways to use the hot reload functionality
7
+ * in development environments.
8
+ */
9
+
10
+ const { createHotReloadManager } = require('../hot-reload');
11
+ const { createDevServer } = require('../dev-server');
12
+ const { createRagPipeline } = require('../../core/create-pipeline');
13
+ const pluginRegistry = require('../../core/plugin-registry');
14
+
15
+ // ============================================================================
16
+ // Example 1: Basic Hot Reload Setup
17
+ // ============================================================================
18
+
19
+ function basicHotReloadExample() {
20
+ console.log('\n=== Example 1: Basic Hot Reload ===\n');
21
+
22
+ // Create hot reload manager
23
+ const hotReload = createHotReloadManager({
24
+ enabled: true,
25
+ watchPaths: ['./src/plugins', './src/mocks'],
26
+ configPath: '.ragrc.json',
27
+ verbose: true,
28
+ });
29
+
30
+ // Listen to events
31
+ hotReload.on('plugin:reloaded', ({ path, duration }) => {
32
+ console.log(`Plugin reloaded: ${path} in ${duration}ms`);
33
+ });
34
+
35
+ hotReload.on('config:reloaded', ({ config }) => {
36
+ console.log('Configuration reloaded:', config.metadata?.name);
37
+ });
38
+
39
+ // Start watching
40
+ hotReload.start().then(() => {
41
+ console.log('Hot reload started');
42
+ });
43
+
44
+ // To stop:
45
+ // hotReload.stop();
46
+ }
47
+
48
+ // ============================================================================
49
+ // Example 2: Hot Reload with Plugin Registry Integration
50
+ // ============================================================================
51
+
52
+ async function hotReloadWithRegistryExample() {
53
+ console.log('\n=== Example 2: Hot Reload with Plugin Registry ===\n');
54
+
55
+ // Create hot reload manager with plugin registry
56
+ const hotReload = createHotReloadManager({
57
+ enabled: true,
58
+ watchPaths: ['./src/plugins'],
59
+ pluginRegistry: pluginRegistry,
60
+ verbose: true,
61
+ preserveState: true, // Preserve plugin state during reloads
62
+ });
63
+
64
+ // Register hooks for advanced control
65
+ hotReload.registerHook('beforeReload', async (data) => {
66
+ console.log(`About to reload ${data.type}: ${data.path}`);
67
+ // Perform any cleanup or preparation
68
+ });
69
+
70
+ hotReload.registerHook('afterReload', async (data) => {
71
+ console.log(`Reload completed for ${data.type}: ${data.path}`);
72
+ // Re-register with plugin registry, update references, etc.
73
+ });
74
+
75
+ hotReload.registerHook('onError', async ({ message, error }) => {
76
+ console.error(`Reload error: ${message}`, error);
77
+ // Send notification, log to service, etc.
78
+ });
79
+
80
+ await hotReload.start();
81
+
82
+ // Get statistics
83
+ setInterval(() => {
84
+ const stats = hotReload.getStats();
85
+ console.log('Reload Stats:', {
86
+ total: stats.totalReloads,
87
+ successful: stats.successfulReloads,
88
+ failed: stats.failedReloads,
89
+ avgTime: Math.round(stats.averageReloadTime) + 'ms',
90
+ });
91
+ }, 60000); // Every minute
92
+ }
93
+
94
+ // ============================================================================
95
+ // Example 3: Development Server with Hot Reload
96
+ // ============================================================================
97
+
98
+ async function devServerExample() {
99
+ console.log('\n=== Example 3: Development Server ===\n');
100
+
101
+ // Create development server with integrated hot reload
102
+ const devServer = createDevServer({
103
+ port: 3000,
104
+ host: 'localhost',
105
+ watchPaths: ['./src/plugins', './src/mocks'],
106
+ configPath: '.ragrc.json',
107
+ verbose: true,
108
+ autoReload: true,
109
+ notifyOnReload: true,
110
+ });
111
+
112
+ // Listen to server events
113
+ devServer.on('started', () => {
114
+ console.log('Development server started');
115
+ console.log(devServer.getStatistics());
116
+ });
117
+
118
+ devServer.on('plugin:reloaded', ({ path, duration }) => {
119
+ console.log(`✓ Plugin reloaded: ${path} (${duration}ms)`);
120
+ });
121
+
122
+ devServer.on('config:reloaded', ({ path, duration }) => {
123
+ console.log(`✓ Config reloaded: ${path} (${duration}ms)`);
124
+ });
125
+
126
+ devServer.on('notification', ({ message, type }) => {
127
+ console.log(`[${type.toUpperCase()}] ${message}`);
128
+ });
129
+
130
+ // Start the server
131
+ await devServer.start();
132
+
133
+ // Display statistics periodically
134
+ setInterval(() => {
135
+ console.log(devServer.getStatistics());
136
+ }, 300000); // Every 5 minutes
137
+
138
+ // Handle graceful shutdown
139
+ process.on('SIGINT', async () => {
140
+ console.log('\nShutting down...');
141
+ await devServer.stop();
142
+ process.exit(0);
143
+ });
144
+ }
145
+
146
+ // ============================================================================
147
+ // Example 4: Hot Reload with RAG Pipeline
148
+ // ============================================================================
149
+
150
+ async function hotReloadWithPipelineExample() {
151
+ console.log('\n=== Example 4: Hot Reload with Pipeline ===\n');
152
+
153
+ // Create pipeline
154
+ const pipeline = await createRagPipeline({
155
+ configPath: '.ragrc.json',
156
+ });
157
+
158
+ // Create dev server with pipeline integration
159
+ const devServer = createDevServer({
160
+ watchPaths: ['./src/plugins', './src/mocks'],
161
+ configPath: '.ragrc.json',
162
+ verbose: true,
163
+ pluginRegistry: pluginRegistry,
164
+ pipeline: pipeline,
165
+ });
166
+
167
+ // When config changes, pipeline will be reinitialized automatically
168
+ devServer.on('config:reloaded', async () => {
169
+ console.log('Pipeline configuration updated');
170
+ // Pipeline is automatically reinitialized by dev server
171
+ });
172
+
173
+ // When plugins change, they're hot-reloaded
174
+ devServer.on('plugin:reloaded', async ({ path }) => {
175
+ console.log(`Plugin ${path} updated and reloaded`);
176
+ // Plugin is automatically updated in registry
177
+ });
178
+
179
+ await devServer.start();
180
+ }
181
+
182
+ // ============================================================================
183
+ // Example 5: Custom State Preservation
184
+ // ============================================================================
185
+
186
+ async function customStatePreservationExample() {
187
+ console.log('\n=== Example 5: Custom State Preservation ===\n');
188
+
189
+ const hotReload = createHotReloadManager({
190
+ enabled: true,
191
+ watchPaths: ['./src/plugins'],
192
+ preserveState: true,
193
+ verbose: true,
194
+ });
195
+
196
+ // Hook into state preservation
197
+ hotReload.registerHook('onStatePreserve', async ({ path, state }) => {
198
+ console.log(`Preserving state for ${path}:`, state);
199
+ // You can save state to external storage here
200
+ });
201
+
202
+ hotReload.registerHook('onStateRestore', async ({ plugin, state }) => {
203
+ console.log('Restoring state:', state);
204
+ // You can restore state from external storage here
205
+ });
206
+
207
+ await hotReload.start();
208
+ }
209
+
210
+ // ============================================================================
211
+ // Example 6: Manual Reload Triggering
212
+ // ============================================================================
213
+
214
+ async function manualReloadExample() {
215
+ console.log('\n=== Example 6: Manual Reload ===\n');
216
+
217
+ const devServer = createDevServer({
218
+ watchPaths: ['./src/plugins'],
219
+ autoReload: false, // Disable automatic reloading
220
+ verbose: true,
221
+ });
222
+
223
+ await devServer.start();
224
+
225
+ // Manually trigger reloads
226
+ await devServer.triggerReload('./src/plugins/my-plugin.js', 'plugin');
227
+ await devServer.triggerReload('.ragrc.json', 'config');
228
+
229
+ console.log('Manual reloads completed');
230
+ }
231
+
232
+ // ============================================================================
233
+ // Example 7: Configuration Validation
234
+ // ============================================================================
235
+
236
+ async function configValidationExample() {
237
+ console.log('\n=== Example 7: Config Validation ===\n');
238
+
239
+ const hotReload = createHotReloadManager({
240
+ enabled: true,
241
+ configPath: '.ragrc.json',
242
+ verbose: true,
243
+ // Custom config validator
244
+ configValidator: (config) => {
245
+ const errors = [];
246
+
247
+ // Validate required fields
248
+ if (!config.metadata || !config.metadata.name) {
249
+ errors.push({ message: 'metadata.name is required' });
250
+ }
251
+
252
+ if (!config.pipeline || !config.pipeline.stages) {
253
+ errors.push({ message: 'pipeline.stages is required' });
254
+ }
255
+
256
+ return {
257
+ valid: errors.length === 0,
258
+ errors,
259
+ };
260
+ },
261
+ });
262
+
263
+ hotReload.on('config:reload-failed', ({ error }) => {
264
+ console.error('Configuration validation failed:', error);
265
+ });
266
+
267
+ await hotReload.start();
268
+ }
269
+
270
+ // ============================================================================
271
+ // Example 8: Development Workflow Integration
272
+ // ============================================================================
273
+
274
+ async function developmentWorkflowExample() {
275
+ console.log('\n=== Example 8: Complete Development Workflow ===\n');
276
+
277
+ // Create a complete development environment
278
+ const devServer = createDevServer({
279
+ port: 3000,
280
+ host: 'localhost',
281
+ watchPaths: ['./src/plugins', './src/mocks', './src/config'],
282
+ configPath: '.ragrc.json',
283
+ verbose: true,
284
+ autoReload: true,
285
+ notifyOnReload: true,
286
+ pluginRegistry: pluginRegistry,
287
+ });
288
+
289
+ // Add custom hooks
290
+ devServer.registerHook('beforeReload', async (data) => {
291
+ console.log(`[BEFORE] Reloading ${data.type}: ${data.path}`);
292
+ // Run pre-reload tasks (tests, linting, etc.)
293
+ });
294
+
295
+ devServer.registerHook('afterReload', async (data) => {
296
+ console.log(`[AFTER] Reloaded ${data.type}: ${data.path}`);
297
+ // Run post-reload tasks (smoke tests, notifications, etc.)
298
+ });
299
+
300
+ // Start server
301
+ await devServer.start();
302
+
303
+ // Log status every 5 minutes
304
+ setInterval(() => {
305
+ const status = devServer.getStatus();
306
+ console.log('\n=== Server Status ===');
307
+ console.log(`Uptime: ${Math.floor(status.uptime / 1000)}s`);
308
+ console.log(`Total Reloads: ${status.hotReload.stats.totalReloads}`);
309
+ console.log(
310
+ `Success Rate: ${
311
+ status.hotReload.stats.totalReloads > 0
312
+ ? Math.round(
313
+ (status.hotReload.stats.successfulReloads /
314
+ status.hotReload.stats.totalReloads) *
315
+ 100,
316
+ ) + '%'
317
+ : 'N/A'
318
+ }`,
319
+ );
320
+ }, 300000);
321
+
322
+ // Handle shutdown
323
+ process.on('SIGINT', async () => {
324
+ console.log('\n\nShutting down development server...');
325
+ console.log(devServer.getStatistics());
326
+ await devServer.stop();
327
+ process.exit(0);
328
+ });
329
+ }
330
+
331
+ // ============================================================================
332
+ // Run Examples
333
+ // ============================================================================
334
+
335
+ // Uncomment the example you want to run:
336
+
337
+ // basicHotReloadExample();
338
+ // hotReloadWithRegistryExample();
339
+ // devServerExample();
340
+ // hotReloadWithPipelineExample();
341
+ // customStatePreservationExample();
342
+ // manualReloadExample();
343
+ // configValidationExample();
344
+ // developmentWorkflowExample();
345
+
346
+ module.exports = {
347
+ basicHotReloadExample,
348
+ hotReloadWithRegistryExample,
349
+ devServerExample,
350
+ hotReloadWithPipelineExample,
351
+ customStatePreservationExample,
352
+ manualReloadExample,
353
+ configValidationExample,
354
+ developmentWorkflowExample,
355
+ };