@objectstack/core 0.6.1 → 0.7.1

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 (56) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/ENHANCED_FEATURES.md +380 -0
  3. package/README.md +299 -12
  4. package/dist/contracts/data-engine.d.ts +39 -22
  5. package/dist/contracts/data-engine.d.ts.map +1 -1
  6. package/dist/contracts/logger.d.ts +63 -0
  7. package/dist/contracts/logger.d.ts.map +1 -0
  8. package/dist/contracts/logger.js +1 -0
  9. package/dist/enhanced-kernel.d.ts +103 -0
  10. package/dist/enhanced-kernel.d.ts.map +1 -0
  11. package/dist/enhanced-kernel.js +403 -0
  12. package/dist/enhanced-kernel.test.d.ts +2 -0
  13. package/dist/enhanced-kernel.test.d.ts.map +1 -0
  14. package/dist/enhanced-kernel.test.js +412 -0
  15. package/dist/index.d.ts +11 -2
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +10 -2
  18. package/dist/kernel-base.d.ts +84 -0
  19. package/dist/kernel-base.d.ts.map +1 -0
  20. package/dist/kernel-base.js +219 -0
  21. package/dist/kernel.d.ts +11 -18
  22. package/dist/kernel.d.ts.map +1 -1
  23. package/dist/kernel.js +43 -114
  24. package/dist/kernel.test.d.ts +2 -0
  25. package/dist/kernel.test.d.ts.map +1 -0
  26. package/dist/kernel.test.js +161 -0
  27. package/dist/logger.d.ts +70 -0
  28. package/dist/logger.d.ts.map +1 -0
  29. package/dist/logger.js +268 -0
  30. package/dist/logger.test.d.ts +2 -0
  31. package/dist/logger.test.d.ts.map +1 -0
  32. package/dist/logger.test.js +92 -0
  33. package/dist/plugin-loader.d.ts +148 -0
  34. package/dist/plugin-loader.d.ts.map +1 -0
  35. package/dist/plugin-loader.js +287 -0
  36. package/dist/plugin-loader.test.d.ts +2 -0
  37. package/dist/plugin-loader.test.d.ts.map +1 -0
  38. package/dist/plugin-loader.test.js +339 -0
  39. package/dist/types.d.ts +2 -1
  40. package/dist/types.d.ts.map +1 -1
  41. package/examples/enhanced-kernel-example.ts +309 -0
  42. package/package.json +19 -4
  43. package/src/contracts/data-engine.ts +46 -24
  44. package/src/contracts/logger.ts +70 -0
  45. package/src/enhanced-kernel.test.ts +535 -0
  46. package/src/enhanced-kernel.ts +496 -0
  47. package/src/index.ts +23 -2
  48. package/src/kernel-base.ts +256 -0
  49. package/src/kernel.test.ts +200 -0
  50. package/src/kernel.ts +55 -129
  51. package/src/logger.test.ts +116 -0
  52. package/src/logger.ts +306 -0
  53. package/src/plugin-loader.test.ts +412 -0
  54. package/src/plugin-loader.ts +435 -0
  55. package/src/types.ts +2 -1
  56. package/vitest.config.ts +8 -0
@@ -0,0 +1,70 @@
1
+ import type { LoggerConfig } from '@objectstack/spec/system';
2
+ import type { Logger } from '@objectstack/spec/contracts';
3
+ /**
4
+ * Universal Logger Implementation
5
+ *
6
+ * A configurable logger that works in both browser and Node.js environments.
7
+ * - Node.js: Uses Pino for high-performance structured logging
8
+ * - Browser: Simple console-based implementation
9
+ *
10
+ * Features:
11
+ * - Structured logging with multiple formats (json, text, pretty)
12
+ * - Log level filtering
13
+ * - Sensitive data redaction
14
+ * - File logging with rotation (Node.js only via Pino)
15
+ * - Browser console integration
16
+ * - Distributed tracing support (traceId, spanId)
17
+ */
18
+ export declare class ObjectLogger implements Logger {
19
+ private config;
20
+ private isNode;
21
+ private pinoLogger?;
22
+ private pinoInstance?;
23
+ constructor(config?: Partial<LoggerConfig>);
24
+ /**
25
+ * Initialize Pino logger for Node.js
26
+ */
27
+ private initPinoLogger;
28
+ /**
29
+ * Redact sensitive keys from context object (for browser)
30
+ */
31
+ private redactSensitive;
32
+ /**
33
+ * Format log entry for browser
34
+ */
35
+ private formatBrowserLog;
36
+ /**
37
+ * Log using browser console
38
+ */
39
+ private logBrowser;
40
+ /**
41
+ * Public logging methods
42
+ */
43
+ debug(message: string, meta?: Record<string, any>): void;
44
+ info(message: string, meta?: Record<string, any>): void;
45
+ warn(message: string, meta?: Record<string, any>): void;
46
+ error(message: string, error?: Error, meta?: Record<string, any>): void;
47
+ fatal(message: string, error?: Error, meta?: Record<string, any>): void;
48
+ /**
49
+ * Create a child logger with additional context
50
+ * Note: Child loggers share the parent's Pino instance
51
+ */
52
+ child(context: Record<string, any>): ObjectLogger;
53
+ /**
54
+ * Set trace context for distributed tracing
55
+ */
56
+ withTrace(traceId: string, spanId?: string): ObjectLogger;
57
+ /**
58
+ * Cleanup resources
59
+ */
60
+ destroy(): Promise<void>;
61
+ /**
62
+ * Compatibility method for console.log usage
63
+ */
64
+ log(message: string, ...args: any[]): void;
65
+ }
66
+ /**
67
+ * Create a logger instance
68
+ */
69
+ export declare function createLogger(config?: Partial<LoggerConfig>): ObjectLogger;
70
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,MAAM;IACvC,OAAO,CAAC,MAAM,CAAkJ;IAChK,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,YAAY,CAAC,CAAM;gBAEf,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAwB9C;;OAEG;IACH,OAAO,CAAC,cAAc;IA+EtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsCxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQxD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IASvE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IASvE;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY;IAYjD;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY;IAIzD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAG7C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAEzE"}
package/dist/logger.js ADDED
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Universal Logger Implementation
3
+ *
4
+ * A configurable logger that works in both browser and Node.js environments.
5
+ * - Node.js: Uses Pino for high-performance structured logging
6
+ * - Browser: Simple console-based implementation
7
+ *
8
+ * Features:
9
+ * - Structured logging with multiple formats (json, text, pretty)
10
+ * - Log level filtering
11
+ * - Sensitive data redaction
12
+ * - File logging with rotation (Node.js only via Pino)
13
+ * - Browser console integration
14
+ * - Distributed tracing support (traceId, spanId)
15
+ */
16
+ export class ObjectLogger {
17
+ constructor(config = {}) {
18
+ // Detect runtime environment
19
+ this.isNode = typeof process !== 'undefined' && process.versions?.node !== undefined;
20
+ // Set defaults
21
+ this.config = {
22
+ name: config.name,
23
+ level: config.level ?? 'info',
24
+ format: config.format ?? (this.isNode ? 'json' : 'pretty'),
25
+ redact: config.redact ?? ['password', 'token', 'secret', 'key'],
26
+ sourceLocation: config.sourceLocation ?? false,
27
+ file: config.file,
28
+ rotation: config.rotation ?? {
29
+ maxSize: '10m',
30
+ maxFiles: 5
31
+ }
32
+ };
33
+ // Initialize Pino logger for Node.js
34
+ if (this.isNode) {
35
+ this.initPinoLogger();
36
+ }
37
+ }
38
+ /**
39
+ * Initialize Pino logger for Node.js
40
+ */
41
+ initPinoLogger() {
42
+ if (!this.isNode)
43
+ return;
44
+ try {
45
+ // Dynamic import for Pino (Node.js only)
46
+ const pino = require('pino');
47
+ // Build Pino options
48
+ const pinoOptions = {
49
+ level: this.config.level,
50
+ redact: {
51
+ paths: this.config.redact,
52
+ censor: '***REDACTED***'
53
+ }
54
+ };
55
+ // Add name if provided
56
+ if (this.config.name) {
57
+ pinoOptions.name = this.config.name;
58
+ }
59
+ // Transport configuration for pretty printing or file output
60
+ const targets = [];
61
+ // Console transport
62
+ if (this.config.format === 'pretty') {
63
+ targets.push({
64
+ target: 'pino-pretty',
65
+ options: {
66
+ colorize: true,
67
+ translateTime: 'SYS:standard',
68
+ ignore: 'pid,hostname'
69
+ },
70
+ level: this.config.level
71
+ });
72
+ }
73
+ else if (this.config.format === 'json') {
74
+ // JSON to stdout
75
+ targets.push({
76
+ target: 'pino/file',
77
+ options: { destination: 1 }, // stdout
78
+ level: this.config.level
79
+ });
80
+ }
81
+ else {
82
+ // text format (simple)
83
+ targets.push({
84
+ target: 'pino/file',
85
+ options: { destination: 1 },
86
+ level: this.config.level
87
+ });
88
+ }
89
+ // File transport (if configured)
90
+ if (this.config.file) {
91
+ targets.push({
92
+ target: 'pino/file',
93
+ options: {
94
+ destination: this.config.file,
95
+ mkdir: true
96
+ },
97
+ level: this.config.level
98
+ });
99
+ }
100
+ // Create transport
101
+ if (targets.length > 0) {
102
+ pinoOptions.transport = targets.length === 1 ? targets[0] : { targets };
103
+ }
104
+ // Create Pino logger
105
+ this.pinoInstance = pino(pinoOptions);
106
+ this.pinoLogger = this.pinoInstance;
107
+ }
108
+ catch (error) {
109
+ // Fallback to console if Pino is not available
110
+ console.warn('[Logger] Pino not available, falling back to console:', error);
111
+ this.pinoLogger = null;
112
+ }
113
+ }
114
+ /**
115
+ * Redact sensitive keys from context object (for browser)
116
+ */
117
+ redactSensitive(obj) {
118
+ if (!obj || typeof obj !== 'object')
119
+ return obj;
120
+ const redacted = Array.isArray(obj) ? [...obj] : { ...obj };
121
+ for (const key in redacted) {
122
+ const lowerKey = key.toLowerCase();
123
+ const shouldRedact = this.config.redact.some((pattern) => lowerKey.includes(pattern.toLowerCase()));
124
+ if (shouldRedact) {
125
+ redacted[key] = '***REDACTED***';
126
+ }
127
+ else if (typeof redacted[key] === 'object' && redacted[key] !== null) {
128
+ redacted[key] = this.redactSensitive(redacted[key]);
129
+ }
130
+ }
131
+ return redacted;
132
+ }
133
+ /**
134
+ * Format log entry for browser
135
+ */
136
+ formatBrowserLog(level, message, context) {
137
+ if (this.config.format === 'json') {
138
+ return JSON.stringify({
139
+ timestamp: new Date().toISOString(),
140
+ level,
141
+ message,
142
+ ...context
143
+ });
144
+ }
145
+ if (this.config.format === 'text') {
146
+ const parts = [new Date().toISOString(), level.toUpperCase(), message];
147
+ if (context && Object.keys(context).length > 0) {
148
+ parts.push(JSON.stringify(context));
149
+ }
150
+ return parts.join(' | ');
151
+ }
152
+ // Pretty format
153
+ const levelColors = {
154
+ debug: '\x1b[36m', // Cyan
155
+ info: '\x1b[32m', // Green
156
+ warn: '\x1b[33m', // Yellow
157
+ error: '\x1b[31m', // Red
158
+ fatal: '\x1b[35m' // Magenta
159
+ };
160
+ const reset = '\x1b[0m';
161
+ const color = levelColors[level] || '';
162
+ let output = `${color}[${level.toUpperCase()}]${reset} ${message}`;
163
+ if (context && Object.keys(context).length > 0) {
164
+ output += ` ${JSON.stringify(context, null, 2)}`;
165
+ }
166
+ return output;
167
+ }
168
+ /**
169
+ * Log using browser console
170
+ */
171
+ logBrowser(level, message, context, error) {
172
+ const redactedContext = context ? this.redactSensitive(context) : undefined;
173
+ const mergedContext = error ? { ...redactedContext, error: { message: error.message, stack: error.stack } } : redactedContext;
174
+ const formatted = this.formatBrowserLog(level, message, mergedContext);
175
+ const consoleMethod = level === 'debug' ? 'debug' :
176
+ level === 'info' ? 'log' :
177
+ level === 'warn' ? 'warn' :
178
+ level === 'error' || level === 'fatal' ? 'error' :
179
+ 'log';
180
+ console[consoleMethod](formatted);
181
+ }
182
+ /**
183
+ * Public logging methods
184
+ */
185
+ debug(message, meta) {
186
+ if (this.isNode && this.pinoLogger) {
187
+ this.pinoLogger.debug(meta || {}, message);
188
+ }
189
+ else {
190
+ this.logBrowser('debug', message, meta);
191
+ }
192
+ }
193
+ info(message, meta) {
194
+ if (this.isNode && this.pinoLogger) {
195
+ this.pinoLogger.info(meta || {}, message);
196
+ }
197
+ else {
198
+ this.logBrowser('info', message, meta);
199
+ }
200
+ }
201
+ warn(message, meta) {
202
+ if (this.isNode && this.pinoLogger) {
203
+ this.pinoLogger.warn(meta || {}, message);
204
+ }
205
+ else {
206
+ this.logBrowser('warn', message, meta);
207
+ }
208
+ }
209
+ error(message, error, meta) {
210
+ if (this.isNode && this.pinoLogger) {
211
+ const errorContext = error ? { err: error, ...meta } : meta || {};
212
+ this.pinoLogger.error(errorContext, message);
213
+ }
214
+ else {
215
+ this.logBrowser('error', message, meta, error);
216
+ }
217
+ }
218
+ fatal(message, error, meta) {
219
+ if (this.isNode && this.pinoLogger) {
220
+ const errorContext = error ? { err: error, ...meta } : meta || {};
221
+ this.pinoLogger.fatal(errorContext, message);
222
+ }
223
+ else {
224
+ this.logBrowser('fatal', message, meta, error);
225
+ }
226
+ }
227
+ /**
228
+ * Create a child logger with additional context
229
+ * Note: Child loggers share the parent's Pino instance
230
+ */
231
+ child(context) {
232
+ const childLogger = new ObjectLogger(this.config);
233
+ // For Node.js with Pino, create a Pino child logger
234
+ if (this.isNode && this.pinoInstance) {
235
+ childLogger.pinoLogger = this.pinoInstance.child(context);
236
+ childLogger.pinoInstance = this.pinoInstance;
237
+ }
238
+ return childLogger;
239
+ }
240
+ /**
241
+ * Set trace context for distributed tracing
242
+ */
243
+ withTrace(traceId, spanId) {
244
+ return this.child({ traceId, spanId });
245
+ }
246
+ /**
247
+ * Cleanup resources
248
+ */
249
+ async destroy() {
250
+ if (this.pinoLogger && this.pinoLogger.flush) {
251
+ await new Promise((resolve) => {
252
+ this.pinoLogger.flush(() => resolve());
253
+ });
254
+ }
255
+ }
256
+ /**
257
+ * Compatibility method for console.log usage
258
+ */
259
+ log(message, ...args) {
260
+ this.info(message, args.length > 0 ? { args } : undefined);
261
+ }
262
+ }
263
+ /**
264
+ * Create a logger instance
265
+ */
266
+ export function createLogger(config) {
267
+ return new ObjectLogger(config);
268
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logger.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../src/logger.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,92 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { createLogger } from './logger';
3
+ describe('ObjectLogger', () => {
4
+ let logger;
5
+ beforeEach(() => {
6
+ logger = createLogger();
7
+ });
8
+ afterEach(async () => {
9
+ await logger.destroy();
10
+ });
11
+ describe('Basic Logging', () => {
12
+ it('should create a logger with default config', () => {
13
+ expect(logger).toBeDefined();
14
+ expect(logger.info).toBeDefined();
15
+ expect(logger.debug).toBeDefined();
16
+ expect(logger.warn).toBeDefined();
17
+ expect(logger.error).toBeDefined();
18
+ });
19
+ it('should log info messages', () => {
20
+ expect(() => logger.info('Test message')).not.toThrow();
21
+ });
22
+ it('should log debug messages', () => {
23
+ expect(() => logger.debug('Debug message')).not.toThrow();
24
+ });
25
+ it('should log warn messages', () => {
26
+ expect(() => logger.warn('Warning message')).not.toThrow();
27
+ });
28
+ it('should log error messages', () => {
29
+ const error = new Error('Test error');
30
+ expect(() => logger.error('Error occurred', error)).not.toThrow();
31
+ });
32
+ it('should log with metadata', () => {
33
+ expect(() => logger.info('Message with metadata', { userId: '123', action: 'login' })).not.toThrow();
34
+ });
35
+ });
36
+ describe('Configuration', () => {
37
+ it('should respect log level configuration', async () => {
38
+ const warnLogger = createLogger({ level: 'warn' });
39
+ // These should not throw but might not output anything
40
+ expect(() => warnLogger.debug('Debug message')).not.toThrow();
41
+ expect(() => warnLogger.info('Info message')).not.toThrow();
42
+ expect(() => warnLogger.warn('Warning message')).not.toThrow();
43
+ await warnLogger.destroy();
44
+ });
45
+ it('should support different formats', async () => {
46
+ const jsonLogger = createLogger({ format: 'json' });
47
+ const textLogger = createLogger({ format: 'text' });
48
+ const prettyLogger = createLogger({ format: 'pretty' });
49
+ expect(() => jsonLogger.info('JSON format')).not.toThrow();
50
+ expect(() => textLogger.info('Text format')).not.toThrow();
51
+ expect(() => prettyLogger.info('Pretty format')).not.toThrow();
52
+ await jsonLogger.destroy();
53
+ await textLogger.destroy();
54
+ await prettyLogger.destroy();
55
+ });
56
+ it('should redact sensitive keys', async () => {
57
+ const logger = createLogger({ redact: ['password', 'apiKey'] });
58
+ // This should work without exposing the password
59
+ expect(() => logger.info('User login', {
60
+ username: 'john',
61
+ password: 'secret123',
62
+ apiKey: 'key-12345'
63
+ })).not.toThrow();
64
+ await logger.destroy();
65
+ });
66
+ });
67
+ describe('Child Loggers', () => {
68
+ it('should create child logger with context', () => {
69
+ const childLogger = logger.child({ service: 'api', requestId: '123' });
70
+ expect(childLogger).toBeDefined();
71
+ expect(() => childLogger.info('Child log message')).not.toThrow();
72
+ });
73
+ it('should support trace context', () => {
74
+ const tracedLogger = logger.withTrace('trace-123', 'span-456');
75
+ expect(tracedLogger).toBeDefined();
76
+ expect(() => tracedLogger.info('Traced message')).not.toThrow();
77
+ });
78
+ });
79
+ describe('Environment Detection', () => {
80
+ it('should detect Node.js environment', async () => {
81
+ // This test runs in Node.js, so logger should detect it
82
+ const nodeLogger = createLogger({ format: 'json' });
83
+ expect(() => nodeLogger.info('Node environment')).not.toThrow();
84
+ await nodeLogger.destroy();
85
+ });
86
+ });
87
+ describe('Compatibility', () => {
88
+ it('should support console.log compatibility', () => {
89
+ expect(() => logger.log('Compatible log')).not.toThrow();
90
+ });
91
+ });
92
+ });
@@ -0,0 +1,148 @@
1
+ import { Plugin, PluginContext } from './types.js';
2
+ import type { Logger } from '@objectstack/spec/contracts';
3
+ import { z } from 'zod';
4
+ /**
5
+ * Service Lifecycle Types
6
+ * Defines how services are instantiated and managed
7
+ */
8
+ export declare enum ServiceLifecycle {
9
+ /** Single instance shared across all requests */
10
+ SINGLETON = "singleton",
11
+ /** New instance created for each request */
12
+ TRANSIENT = "transient",
13
+ /** New instance per scope (e.g., per HTTP request) */
14
+ SCOPED = "scoped"
15
+ }
16
+ /**
17
+ * Service Factory
18
+ * Function that creates a service instance
19
+ */
20
+ export type ServiceFactory<T = any> = (ctx: PluginContext) => T | Promise<T>;
21
+ /**
22
+ * Service Registration Options
23
+ */
24
+ export interface ServiceRegistration {
25
+ name: string;
26
+ factory: ServiceFactory;
27
+ lifecycle: ServiceLifecycle;
28
+ dependencies?: string[];
29
+ }
30
+ /**
31
+ * Plugin Configuration Validator
32
+ * Uses Zod for runtime validation of plugin configurations
33
+ */
34
+ export interface PluginConfigValidator {
35
+ schema: z.ZodSchema;
36
+ validate(config: any): any;
37
+ }
38
+ /**
39
+ * Plugin Metadata with Enhanced Features
40
+ */
41
+ export interface PluginMetadata extends Plugin {
42
+ /** Semantic version (e.g., "1.0.0") */
43
+ version: string;
44
+ /** Configuration schema for validation */
45
+ configSchema?: z.ZodSchema;
46
+ /** Plugin signature for security verification */
47
+ signature?: string;
48
+ /** Plugin health check function */
49
+ healthCheck?(): Promise<PluginHealthStatus>;
50
+ /** Startup timeout in milliseconds (default: 30000) */
51
+ startupTimeout?: number;
52
+ /** Whether plugin supports hot reload */
53
+ hotReloadable?: boolean;
54
+ }
55
+ /**
56
+ * Plugin Health Status
57
+ */
58
+ export interface PluginHealthStatus {
59
+ healthy: boolean;
60
+ message?: string;
61
+ details?: Record<string, any>;
62
+ lastCheck?: Date;
63
+ }
64
+ /**
65
+ * Plugin Load Result
66
+ */
67
+ export interface PluginLoadResult {
68
+ success: boolean;
69
+ plugin?: PluginMetadata;
70
+ error?: Error;
71
+ loadTime?: number;
72
+ }
73
+ /**
74
+ * Plugin Startup Result
75
+ */
76
+ export interface PluginStartupResult {
77
+ success: boolean;
78
+ pluginName: string;
79
+ startTime?: number;
80
+ error?: Error;
81
+ timedOut?: boolean;
82
+ }
83
+ /**
84
+ * Version Compatibility Result
85
+ */
86
+ export interface VersionCompatibility {
87
+ compatible: boolean;
88
+ pluginVersion: string;
89
+ requiredVersion?: string;
90
+ message?: string;
91
+ }
92
+ /**
93
+ * Enhanced Plugin Loader
94
+ * Provides advanced plugin loading capabilities with validation, security, and lifecycle management
95
+ */
96
+ export declare class PluginLoader {
97
+ private logger;
98
+ private loadedPlugins;
99
+ private serviceFactories;
100
+ private serviceInstances;
101
+ private scopedServices;
102
+ constructor(logger: Logger);
103
+ /**
104
+ * Load a plugin asynchronously with validation
105
+ */
106
+ loadPlugin(plugin: Plugin): Promise<PluginLoadResult>;
107
+ /**
108
+ * Register a service with factory function
109
+ */
110
+ registerServiceFactory(registration: ServiceRegistration): void;
111
+ /**
112
+ * Get or create a service instance based on lifecycle type
113
+ */
114
+ getService<T>(name: string, scopeId?: string): Promise<T>;
115
+ /**
116
+ * Register a static service instance (legacy support)
117
+ */
118
+ registerService(name: string, service: any): void;
119
+ /**
120
+ * Detect circular dependencies in service factories
121
+ * Note: This only detects cycles in service dependencies, not plugin dependencies.
122
+ * Plugin dependency cycles are detected in the kernel's resolveDependencies method.
123
+ */
124
+ detectCircularDependencies(): string[];
125
+ /**
126
+ * Check plugin health
127
+ */
128
+ checkPluginHealth(pluginName: string): Promise<PluginHealthStatus>;
129
+ /**
130
+ * Clear scoped services for a scope
131
+ */
132
+ clearScope(scopeId: string): void;
133
+ /**
134
+ * Get all loaded plugins
135
+ */
136
+ getLoadedPlugins(): Map<string, PluginMetadata>;
137
+ private toPluginMetadata;
138
+ private validatePluginStructure;
139
+ private checkVersionCompatibility;
140
+ private isValidSemanticVersion;
141
+ private validatePluginConfig;
142
+ private verifyPluginSignature;
143
+ private getSingletonService;
144
+ private createTransientService;
145
+ private getScopedService;
146
+ private createServiceInstance;
147
+ }
148
+ //# sourceMappingURL=plugin-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../src/plugin-loader.ts"],"names":[],"mappings":"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"}