@objectstack/core 0.9.1 → 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.
- package/{ENHANCED_FEATURES.md → ADVANCED_FEATURES.md} +13 -13
- package/CHANGELOG.md +21 -0
- package/PHASE2_IMPLEMENTATION.md +388 -0
- package/README.md +12 -341
- package/REFACTORING_SUMMARY.md +40 -0
- package/dist/api-registry-plugin.test.js +23 -21
- package/dist/api-registry.test.js +2 -2
- package/dist/dependency-resolver.d.ts +62 -0
- package/dist/dependency-resolver.d.ts.map +1 -0
- package/dist/dependency-resolver.js +317 -0
- package/dist/dependency-resolver.test.d.ts +2 -0
- package/dist/dependency-resolver.test.d.ts.map +1 -0
- package/dist/dependency-resolver.test.js +241 -0
- package/dist/health-monitor.d.ts +65 -0
- package/dist/health-monitor.d.ts.map +1 -0
- package/dist/health-monitor.js +269 -0
- package/dist/health-monitor.test.d.ts +2 -0
- package/dist/health-monitor.test.d.ts.map +1 -0
- package/dist/health-monitor.test.js +68 -0
- package/dist/hot-reload.d.ts +79 -0
- package/dist/hot-reload.d.ts.map +1 -0
- package/dist/hot-reload.js +313 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/kernel-base.d.ts +2 -2
- package/dist/kernel-base.js +2 -2
- package/dist/kernel.d.ts +89 -31
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +430 -73
- package/dist/kernel.test.js +375 -122
- package/dist/lite-kernel.d.ts +55 -0
- package/dist/lite-kernel.d.ts.map +1 -0
- package/dist/lite-kernel.js +112 -0
- package/dist/lite-kernel.test.d.ts +2 -0
- package/dist/lite-kernel.test.d.ts.map +1 -0
- package/dist/lite-kernel.test.js +161 -0
- package/dist/logger.d.ts +2 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +26 -7
- package/dist/plugin-loader.d.ts +15 -0
- package/dist/plugin-loader.d.ts.map +1 -1
- package/dist/plugin-loader.js +40 -10
- package/dist/plugin-loader.test.js +9 -0
- package/dist/security/index.d.ts +3 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +4 -0
- package/dist/security/permission-manager.d.ts +96 -0
- package/dist/security/permission-manager.d.ts.map +1 -0
- package/dist/security/permission-manager.js +235 -0
- package/dist/security/permission-manager.test.d.ts +2 -0
- package/dist/security/permission-manager.test.d.ts.map +1 -0
- package/dist/security/permission-manager.test.js +220 -0
- package/dist/security/plugin-permission-enforcer.d.ts +1 -1
- package/dist/security/sandbox-runtime.d.ts +115 -0
- package/dist/security/sandbox-runtime.d.ts.map +1 -0
- package/dist/security/sandbox-runtime.js +310 -0
- package/dist/security/security-scanner.d.ts +92 -0
- package/dist/security/security-scanner.d.ts.map +1 -0
- package/dist/security/security-scanner.js +273 -0
- package/examples/{enhanced-kernel-example.ts → kernel-features-example.ts} +6 -6
- package/examples/phase2-integration.ts +355 -0
- package/package.json +3 -2
- package/src/api-registry-plugin.test.ts +23 -21
- package/src/api-registry.test.ts +2 -2
- package/src/dependency-resolver.test.ts +287 -0
- package/src/dependency-resolver.ts +388 -0
- package/src/health-monitor.test.ts +81 -0
- package/src/health-monitor.ts +316 -0
- package/src/hot-reload.ts +388 -0
- package/src/index.ts +6 -1
- package/src/kernel-base.ts +2 -2
- package/src/kernel.test.ts +471 -134
- package/src/kernel.ts +518 -76
- package/src/lite-kernel.test.ts +200 -0
- package/src/lite-kernel.ts +135 -0
- package/src/logger.ts +28 -7
- package/src/plugin-loader.test.ts +10 -1
- package/src/plugin-loader.ts +49 -13
- package/src/security/index.ts +19 -0
- package/src/security/permission-manager.test.ts +256 -0
- package/src/security/permission-manager.ts +336 -0
- package/src/security/plugin-permission-enforcer.test.ts +1 -1
- package/src/security/plugin-permission-enforcer.ts +1 -1
- package/src/security/sandbox-runtime.ts +432 -0
- package/src/security/security-scanner.ts +365 -0
- package/dist/enhanced-kernel.d.ts +0 -103
- package/dist/enhanced-kernel.d.ts.map +0 -1
- package/dist/enhanced-kernel.js +0 -403
- package/dist/enhanced-kernel.test.d.ts +0 -2
- package/dist/enhanced-kernel.test.d.ts.map +0 -1
- package/dist/enhanced-kernel.test.js +0 -412
- package/src/enhanced-kernel.test.ts +0 -535
- package/src/enhanced-kernel.ts +0 -496
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Health Monitor
|
|
3
|
+
*
|
|
4
|
+
* Monitors plugin health status and performs automatic recovery actions.
|
|
5
|
+
* Implements the advanced lifecycle health monitoring protocol.
|
|
6
|
+
*/
|
|
7
|
+
export class PluginHealthMonitor {
|
|
8
|
+
constructor(logger) {
|
|
9
|
+
this.healthChecks = new Map();
|
|
10
|
+
this.healthStatus = new Map();
|
|
11
|
+
this.healthReports = new Map();
|
|
12
|
+
this.checkIntervals = new Map();
|
|
13
|
+
this.failureCounters = new Map();
|
|
14
|
+
this.successCounters = new Map();
|
|
15
|
+
this.restartAttempts = new Map();
|
|
16
|
+
this.logger = logger.child({ component: 'HealthMonitor' });
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Register a plugin for health monitoring
|
|
20
|
+
*/
|
|
21
|
+
registerPlugin(pluginName, config) {
|
|
22
|
+
this.healthChecks.set(pluginName, config);
|
|
23
|
+
this.healthStatus.set(pluginName, 'unknown');
|
|
24
|
+
this.failureCounters.set(pluginName, 0);
|
|
25
|
+
this.successCounters.set(pluginName, 0);
|
|
26
|
+
this.restartAttempts.set(pluginName, 0);
|
|
27
|
+
this.logger.info('Plugin registered for health monitoring', {
|
|
28
|
+
plugin: pluginName,
|
|
29
|
+
interval: config.interval
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Start monitoring a plugin
|
|
34
|
+
*/
|
|
35
|
+
startMonitoring(pluginName, plugin) {
|
|
36
|
+
const config = this.healthChecks.get(pluginName);
|
|
37
|
+
if (!config) {
|
|
38
|
+
this.logger.warn('Cannot start monitoring - plugin not registered', { plugin: pluginName });
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Clear any existing interval
|
|
42
|
+
this.stopMonitoring(pluginName);
|
|
43
|
+
// Set up periodic health checks
|
|
44
|
+
const interval = setInterval(() => {
|
|
45
|
+
this.performHealthCheck(pluginName, plugin, config).catch(error => {
|
|
46
|
+
this.logger.error('Health check failed with error', {
|
|
47
|
+
plugin: pluginName,
|
|
48
|
+
error
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}, config.interval);
|
|
52
|
+
this.checkIntervals.set(pluginName, interval);
|
|
53
|
+
this.logger.info('Health monitoring started', { plugin: pluginName });
|
|
54
|
+
// Perform initial health check
|
|
55
|
+
this.performHealthCheck(pluginName, plugin, config).catch(error => {
|
|
56
|
+
this.logger.error('Initial health check failed', {
|
|
57
|
+
plugin: pluginName,
|
|
58
|
+
error
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Stop monitoring a plugin
|
|
64
|
+
*/
|
|
65
|
+
stopMonitoring(pluginName) {
|
|
66
|
+
const interval = this.checkIntervals.get(pluginName);
|
|
67
|
+
if (interval) {
|
|
68
|
+
clearInterval(interval);
|
|
69
|
+
this.checkIntervals.delete(pluginName);
|
|
70
|
+
this.logger.info('Health monitoring stopped', { plugin: pluginName });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Perform a health check on a plugin
|
|
75
|
+
*/
|
|
76
|
+
async performHealthCheck(pluginName, plugin, config) {
|
|
77
|
+
const startTime = Date.now();
|
|
78
|
+
let status = 'healthy';
|
|
79
|
+
let message;
|
|
80
|
+
const checks = [];
|
|
81
|
+
try {
|
|
82
|
+
// Check if plugin has a custom health check method
|
|
83
|
+
if (config.checkMethod && typeof plugin[config.checkMethod] === 'function') {
|
|
84
|
+
const checkResult = await Promise.race([
|
|
85
|
+
plugin[config.checkMethod](),
|
|
86
|
+
this.timeout(config.timeout, `Health check timeout after ${config.timeout}ms`)
|
|
87
|
+
]);
|
|
88
|
+
if (checkResult === false || (checkResult && checkResult.status === 'unhealthy')) {
|
|
89
|
+
status = 'unhealthy';
|
|
90
|
+
message = checkResult?.message || 'Custom health check failed';
|
|
91
|
+
checks.push({ name: config.checkMethod, status: 'failed', message });
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
checks.push({ name: config.checkMethod, status: 'passed' });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Default health check - just verify plugin is loaded
|
|
99
|
+
checks.push({ name: 'plugin-loaded', status: 'passed' });
|
|
100
|
+
}
|
|
101
|
+
// Update counters based on result
|
|
102
|
+
if (status === 'healthy') {
|
|
103
|
+
this.successCounters.set(pluginName, (this.successCounters.get(pluginName) || 0) + 1);
|
|
104
|
+
this.failureCounters.set(pluginName, 0);
|
|
105
|
+
// Recover from unhealthy state if we have enough successes
|
|
106
|
+
const currentStatus = this.healthStatus.get(pluginName);
|
|
107
|
+
if (currentStatus === 'unhealthy' || currentStatus === 'degraded') {
|
|
108
|
+
const successCount = this.successCounters.get(pluginName) || 0;
|
|
109
|
+
if (successCount >= config.successThreshold) {
|
|
110
|
+
this.healthStatus.set(pluginName, 'healthy');
|
|
111
|
+
this.logger.info('Plugin recovered to healthy state', { plugin: pluginName });
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.healthStatus.set(pluginName, 'recovering');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
this.healthStatus.set(pluginName, 'healthy');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
this.failureCounters.set(pluginName, (this.failureCounters.get(pluginName) || 0) + 1);
|
|
123
|
+
this.successCounters.set(pluginName, 0);
|
|
124
|
+
const failureCount = this.failureCounters.get(pluginName) || 0;
|
|
125
|
+
if (failureCount >= config.failureThreshold) {
|
|
126
|
+
this.healthStatus.set(pluginName, 'unhealthy');
|
|
127
|
+
this.logger.warn('Plugin marked as unhealthy', {
|
|
128
|
+
plugin: pluginName,
|
|
129
|
+
failures: failureCount
|
|
130
|
+
});
|
|
131
|
+
// Attempt auto-restart if configured
|
|
132
|
+
if (config.autoRestart) {
|
|
133
|
+
await this.attemptRestart(pluginName, plugin, config);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this.healthStatus.set(pluginName, 'degraded');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
status = 'failed';
|
|
143
|
+
message = error instanceof Error ? error.message : 'Unknown error';
|
|
144
|
+
this.failureCounters.set(pluginName, (this.failureCounters.get(pluginName) || 0) + 1);
|
|
145
|
+
this.healthStatus.set(pluginName, 'failed');
|
|
146
|
+
checks.push({
|
|
147
|
+
name: 'health-check',
|
|
148
|
+
status: 'failed',
|
|
149
|
+
message: message
|
|
150
|
+
});
|
|
151
|
+
this.logger.error('Health check exception', {
|
|
152
|
+
plugin: pluginName,
|
|
153
|
+
error
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// Create health report
|
|
157
|
+
const report = {
|
|
158
|
+
status: this.healthStatus.get(pluginName) || 'unknown',
|
|
159
|
+
timestamp: new Date().toISOString(),
|
|
160
|
+
message,
|
|
161
|
+
metrics: {
|
|
162
|
+
uptime: Date.now() - startTime,
|
|
163
|
+
},
|
|
164
|
+
checks: checks.length > 0 ? checks : undefined,
|
|
165
|
+
};
|
|
166
|
+
this.healthReports.set(pluginName, report);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Attempt to restart a plugin
|
|
170
|
+
*/
|
|
171
|
+
async attemptRestart(pluginName, plugin, config) {
|
|
172
|
+
const attempts = this.restartAttempts.get(pluginName) || 0;
|
|
173
|
+
if (attempts >= config.maxRestartAttempts) {
|
|
174
|
+
this.logger.error('Max restart attempts reached, giving up', {
|
|
175
|
+
plugin: pluginName,
|
|
176
|
+
attempts
|
|
177
|
+
});
|
|
178
|
+
this.healthStatus.set(pluginName, 'failed');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this.restartAttempts.set(pluginName, attempts + 1);
|
|
182
|
+
// Calculate backoff delay
|
|
183
|
+
const delay = this.calculateBackoff(attempts, config.restartBackoff);
|
|
184
|
+
this.logger.info('Scheduling plugin restart', {
|
|
185
|
+
plugin: pluginName,
|
|
186
|
+
attempt: attempts + 1,
|
|
187
|
+
delay
|
|
188
|
+
});
|
|
189
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
190
|
+
try {
|
|
191
|
+
// Call destroy and init to restart
|
|
192
|
+
if (plugin.destroy) {
|
|
193
|
+
await plugin.destroy();
|
|
194
|
+
}
|
|
195
|
+
// Note: Full restart would require kernel context
|
|
196
|
+
// This is a simplified version - actual implementation would need kernel integration
|
|
197
|
+
this.logger.info('Plugin restarted', { plugin: pluginName });
|
|
198
|
+
// Reset counters on successful restart
|
|
199
|
+
this.failureCounters.set(pluginName, 0);
|
|
200
|
+
this.successCounters.set(pluginName, 0);
|
|
201
|
+
this.healthStatus.set(pluginName, 'recovering');
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
this.logger.error('Plugin restart failed', {
|
|
205
|
+
plugin: pluginName,
|
|
206
|
+
error
|
|
207
|
+
});
|
|
208
|
+
this.healthStatus.set(pluginName, 'failed');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Calculate backoff delay for restarts
|
|
213
|
+
*/
|
|
214
|
+
calculateBackoff(attempt, strategy) {
|
|
215
|
+
const baseDelay = 1000; // 1 second base
|
|
216
|
+
switch (strategy) {
|
|
217
|
+
case 'fixed':
|
|
218
|
+
return baseDelay;
|
|
219
|
+
case 'linear':
|
|
220
|
+
return baseDelay * (attempt + 1);
|
|
221
|
+
case 'exponential':
|
|
222
|
+
return baseDelay * Math.pow(2, attempt);
|
|
223
|
+
default:
|
|
224
|
+
return baseDelay;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Get current health status of a plugin
|
|
229
|
+
*/
|
|
230
|
+
getHealthStatus(pluginName) {
|
|
231
|
+
return this.healthStatus.get(pluginName);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Get latest health report for a plugin
|
|
235
|
+
*/
|
|
236
|
+
getHealthReport(pluginName) {
|
|
237
|
+
return this.healthReports.get(pluginName);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get all health statuses
|
|
241
|
+
*/
|
|
242
|
+
getAllHealthStatuses() {
|
|
243
|
+
return new Map(this.healthStatus);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Shutdown health monitor
|
|
247
|
+
*/
|
|
248
|
+
shutdown() {
|
|
249
|
+
// Stop all monitoring intervals
|
|
250
|
+
for (const pluginName of this.checkIntervals.keys()) {
|
|
251
|
+
this.stopMonitoring(pluginName);
|
|
252
|
+
}
|
|
253
|
+
this.healthChecks.clear();
|
|
254
|
+
this.healthStatus.clear();
|
|
255
|
+
this.healthReports.clear();
|
|
256
|
+
this.failureCounters.clear();
|
|
257
|
+
this.successCounters.clear();
|
|
258
|
+
this.restartAttempts.clear();
|
|
259
|
+
this.logger.info('Health monitor shutdown complete');
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Timeout helper
|
|
263
|
+
*/
|
|
264
|
+
timeout(ms, message) {
|
|
265
|
+
return new Promise((_, reject) => {
|
|
266
|
+
setTimeout(() => reject(new Error(message)), ms);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-monitor.test.d.ts","sourceRoot":"","sources":["../src/health-monitor.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { PluginHealthMonitor } from './health-monitor.js';
|
|
3
|
+
import { createLogger } from './logger.js';
|
|
4
|
+
describe('PluginHealthMonitor', () => {
|
|
5
|
+
let monitor;
|
|
6
|
+
let logger;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
logger = createLogger({ level: 'silent' });
|
|
9
|
+
monitor = new PluginHealthMonitor(logger);
|
|
10
|
+
});
|
|
11
|
+
it('should register plugin for health monitoring', () => {
|
|
12
|
+
const config = {
|
|
13
|
+
interval: 5000,
|
|
14
|
+
timeout: 1000,
|
|
15
|
+
failureThreshold: 3,
|
|
16
|
+
successThreshold: 1,
|
|
17
|
+
autoRestart: false,
|
|
18
|
+
maxRestartAttempts: 3,
|
|
19
|
+
restartBackoff: 'exponential',
|
|
20
|
+
};
|
|
21
|
+
monitor.registerPlugin('test-plugin', config);
|
|
22
|
+
expect(monitor.getHealthStatus('test-plugin')).toBe('unknown');
|
|
23
|
+
});
|
|
24
|
+
it('should report healthy status initially', () => {
|
|
25
|
+
const config = {
|
|
26
|
+
interval: 5000,
|
|
27
|
+
timeout: 1000,
|
|
28
|
+
failureThreshold: 3,
|
|
29
|
+
successThreshold: 1,
|
|
30
|
+
autoRestart: false,
|
|
31
|
+
maxRestartAttempts: 3,
|
|
32
|
+
restartBackoff: 'fixed',
|
|
33
|
+
};
|
|
34
|
+
monitor.registerPlugin('test-plugin', config);
|
|
35
|
+
expect(monitor.getHealthStatus('test-plugin')).toBe('unknown');
|
|
36
|
+
});
|
|
37
|
+
it('should get all health statuses', () => {
|
|
38
|
+
const config = {
|
|
39
|
+
interval: 5000,
|
|
40
|
+
timeout: 1000,
|
|
41
|
+
failureThreshold: 3,
|
|
42
|
+
successThreshold: 1,
|
|
43
|
+
autoRestart: false,
|
|
44
|
+
maxRestartAttempts: 3,
|
|
45
|
+
restartBackoff: 'linear',
|
|
46
|
+
};
|
|
47
|
+
monitor.registerPlugin('plugin1', config);
|
|
48
|
+
monitor.registerPlugin('plugin2', config);
|
|
49
|
+
const statuses = monitor.getAllHealthStatuses();
|
|
50
|
+
expect(statuses.size).toBe(2);
|
|
51
|
+
expect(statuses.has('plugin1')).toBe(true);
|
|
52
|
+
expect(statuses.has('plugin2')).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it('should shutdown cleanly', () => {
|
|
55
|
+
const config = {
|
|
56
|
+
interval: 5000,
|
|
57
|
+
timeout: 1000,
|
|
58
|
+
failureThreshold: 3,
|
|
59
|
+
successThreshold: 1,
|
|
60
|
+
autoRestart: false,
|
|
61
|
+
maxRestartAttempts: 3,
|
|
62
|
+
restartBackoff: 'exponential',
|
|
63
|
+
};
|
|
64
|
+
monitor.registerPlugin('test-plugin', config);
|
|
65
|
+
monitor.shutdown();
|
|
66
|
+
expect(monitor.getAllHealthStatuses().size).toBe(0);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { HotReloadConfig } from '@objectstack/spec/kernel';
|
|
2
|
+
import type { ObjectLogger } from './logger.js';
|
|
3
|
+
import type { Plugin } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Plugin State Manager
|
|
6
|
+
*
|
|
7
|
+
* Handles state persistence and restoration during hot reloads
|
|
8
|
+
*/
|
|
9
|
+
declare class PluginStateManager {
|
|
10
|
+
private logger;
|
|
11
|
+
private stateSnapshots;
|
|
12
|
+
private memoryStore;
|
|
13
|
+
constructor(logger: ObjectLogger);
|
|
14
|
+
/**
|
|
15
|
+
* Save plugin state before reload
|
|
16
|
+
*/
|
|
17
|
+
saveState(pluginId: string, version: string, state: Record<string, any>, config: HotReloadConfig): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Restore plugin state after reload
|
|
20
|
+
*/
|
|
21
|
+
restoreState(pluginId: string, snapshotId?: string): Promise<Record<string, any> | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Clear state for a plugin
|
|
24
|
+
*/
|
|
25
|
+
clearState(pluginId: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Calculate simple checksum for state verification
|
|
28
|
+
* WARNING: This is a simple hash for demo purposes.
|
|
29
|
+
* In production, use a cryptographic hash like SHA-256.
|
|
30
|
+
*/
|
|
31
|
+
private calculateChecksum;
|
|
32
|
+
/**
|
|
33
|
+
* Shutdown state manager
|
|
34
|
+
*/
|
|
35
|
+
shutdown(): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Hot Reload Manager
|
|
39
|
+
*
|
|
40
|
+
* Manages hot reloading of plugins with state preservation
|
|
41
|
+
*/
|
|
42
|
+
export declare class HotReloadManager {
|
|
43
|
+
private logger;
|
|
44
|
+
private stateManager;
|
|
45
|
+
private reloadConfigs;
|
|
46
|
+
private watchHandles;
|
|
47
|
+
private reloadTimers;
|
|
48
|
+
constructor(logger: ObjectLogger);
|
|
49
|
+
/**
|
|
50
|
+
* Register a plugin for hot reload
|
|
51
|
+
*/
|
|
52
|
+
registerPlugin(pluginName: string, config: HotReloadConfig): void;
|
|
53
|
+
/**
|
|
54
|
+
* Start watching for changes (requires file system integration)
|
|
55
|
+
*/
|
|
56
|
+
startWatching(pluginName: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Stop watching for changes
|
|
59
|
+
*/
|
|
60
|
+
stopWatching(pluginName: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Trigger hot reload for a plugin
|
|
63
|
+
*/
|
|
64
|
+
reloadPlugin(pluginName: string, plugin: Plugin, version: string, getPluginState: () => Record<string, any>, restorePluginState: (state: Record<string, any>) => void): Promise<boolean>;
|
|
65
|
+
/**
|
|
66
|
+
* Schedule a reload with debouncing
|
|
67
|
+
*/
|
|
68
|
+
scheduleReload(pluginName: string, reloadFn: () => Promise<void>): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get state manager for direct access
|
|
71
|
+
*/
|
|
72
|
+
getStateManager(): PluginStateManager;
|
|
73
|
+
/**
|
|
74
|
+
* Shutdown hot reload manager
|
|
75
|
+
*/
|
|
76
|
+
shutdown(): void;
|
|
77
|
+
}
|
|
78
|
+
export {};
|
|
79
|
+
//# sourceMappingURL=hot-reload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hot-reload.d.ts","sourceRoot":"","sources":["../src/hot-reload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAezC;;;;GAIG;AACH,cAAM,kBAAkB;IACtB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,WAAW,CAA0B;gBAEjC,MAAM,EAAE,YAAY;IAIhC;;OAEG;IACG,SAAS,CACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;IA8ClB;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;IAgC3C;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMlC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAazB;;OAEG;IACH,QAAQ,IAAI,IAAI;CAKjB;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,YAAY,CAAqC;gBAE7C,MAAM,EAAE,YAAY;IAKhC;;OAEG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;IAcjE;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAcvC;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAgBtC;;OAEG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzC,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,GACvD,OAAO,CAAC,OAAO,CAAC;IA8EnB;;OAEG;IACH,cAAc,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAC5B,IAAI;IAiCP;;OAEG;IACH,eAAe,IAAI,kBAAkB;IAIrC;;OAEG;IACH,QAAQ,IAAI,IAAI;CAkBjB"}
|