@objectstack/core 0.9.2 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @objectstack/core
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Major version release for ObjectStack Protocol v1.0.
8
+ - Stabilized Protocol Definitions
9
+ - Enhanced Runtime Plugin Support
10
+ - Fixed Type Compliance across Monorepo
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+ - @objectstack/spec@1.0.0
16
+
3
17
  ## 0.9.2
4
18
 
5
19
  ### Patch Changes
package/README.md CHANGED
@@ -1,377 +1,35 @@
1
1
  # @objectstack/core
2
2
 
3
- Microkernel Core for ObjectStack - A lightweight, plugin-based architecture with enterprise-grade features.
4
-
5
- ## Overview
6
-
7
- This package defines the fundamental runtime mechanics of the ObjectStack architecture:
8
- 1. **Dependency Injection (DI)**: Advanced service registry with factory functions and lifecycle management
9
- 2. **Plugin Lifecycle**: `init` (Registration) -> `start` (Execution) -> `destroy` (Cleanup)
10
- 3. **Event Bus**: Simple hook system (`hook`, `trigger`) for event-driven communication
11
- 4. **Configurable Logging**: Universal logger using [Pino](https://github.com/pinojs/pino) for Node.js and simple console for browsers
12
- 5. **Enhanced Features**: Version compatibility, health checks, timeout control, graceful shutdown, and more
13
-
14
- It is completely agnostic of "Data", "HTTP", or "Apps". It only knows `Plugin` and `Service`.
15
-
16
- ## 🤖 AI Development Context
17
-
18
- **Role**: Microkernel / Runtime Orchestrator
19
- **Usage**:
20
- - Use `ObjectKernel` to bootstrap the application.
21
- - Implement `Plugin` interface to add functionality (not business logic directly).
22
- - Use `PluginLoader` features for dependency injection.
23
-
24
- **Architectural Interaction**:
25
- - `Kernel` loads `Plugins`.
26
- - `Plugins` register `Services`.
27
- - `Services` implement logic defined in `spec`.
3
+ The **Kernel** of the ObjectStack architecture. It provides the fundamental building blocks for a modular, plugin-based system.
28
4
 
29
5
  ## Features
30
6
 
31
- ### Core Features
32
- - **Plugin-based Architecture**: Modular microkernel that manages plugin lifecycle
33
- - **Service Registry**: Dependency injection for inter-plugin communication
34
- - **Event/Hook System**: Flexible event-driven communication
35
- - **High-Performance Logging**:
36
- - Node.js: Powered by [Pino](https://github.com/pinojs/pino) - extremely fast, low-overhead structured logging
37
- - Browser: Lightweight console-based logger
38
- - **Environment Detection**: Automatic runtime detection (Node.js/browser)
39
- - **Dependency Resolution**: Automatic topological sorting of plugin dependencies
40
- - **Security**: Automatic sensitive data redaction in logs
41
-
42
- ### Enhanced Features (EnhancedObjectKernel)
43
- - **Async Plugin Loading**: Load plugins asynchronously with validation
44
- - **Version Compatibility**: Semantic versioning support and validation
45
- - **Plugin Signatures**: Security verification (extensible)
46
- - **Configuration Validation**: Zod-based schema validation for plugin configs
47
- - **Service Factories**: Factory-based service instantiation with lifecycle control
48
- - **Service Lifecycles**: Singleton, Transient, and Scoped service management
49
- - **Circular Dependency Detection**: Automatic detection and reporting
50
- - **Lazy Loading**: Services created on-demand
51
- - **Timeout Control**: Configurable timeouts for plugin initialization
52
- - **Failure Rollback**: Automatic rollback on startup failures
53
- - **Health Checks**: Monitor plugin health at runtime
54
- - **Performance Metrics**: Track plugin startup times
55
- - **Graceful Shutdown**: Proper cleanup with timeout control
7
+ - **ObjectKernel**: A robust Dependency Injection (DI) container and plugin manager.
8
+ - **Plugin Architecture**: A standard interface (`Plugin`) with lifecycle hooks (`init`, `start`, `stop`).
9
+ - **Service Management**: Register and resolve services with type safety.
10
+ - **Logging**: Structured logging interface with swappable backends.
56
11
 
57
12
  ## Installation
58
13
 
59
14
  ```bash
60
- npm install @objectstack/core
61
- # or
62
15
  pnpm add @objectstack/core
63
16
  ```
64
17
 
65
- ## Quick Start
66
-
67
- ```typescript
68
- import { ObjectKernel, Plugin, PluginContext } from '@objectstack/core';
69
-
70
- // 1. Define a Plugin
71
- const myPlugin: Plugin = {
72
- name: 'my-plugin',
73
-
74
- async init(ctx: PluginContext) {
75
- ctx.logger.info('Initializing plugin');
76
- ctx.registerService('my-service', { hello: 'world' });
77
- }
78
- };
79
-
80
- // 2. Boot Kernel with logging config
81
- const kernel = new ObjectKernel({
82
- logger: {
83
- level: 'info',
84
- format: 'pretty'
85
- }
86
- });
87
-
88
- kernel.use(myPlugin);
89
- await kernel.bootstrap();
90
-
91
- // 3. Use Service
92
- const service = kernel.getService('my-service');
93
-
94
- // 4. Cleanup
95
- await kernel.shutdown();
96
- ```
97
-
98
- ## 🤖 AI Quick Reference
99
-
100
- **For AI Agents:** This package implements a microkernel architecture. Key concepts:
101
-
102
- 1. **Plugin Lifecycle**: `init()` → `start()` → `destroy()`
103
- 2. **Service Registry**: Share functionality via `ctx.registerService(name, service)` and `ctx.getService(name)`
104
- 3. **Dependencies**: Declare plugin dependencies for automatic load ordering
105
- 4. **Hooks/Events**: Decouple plugins with `ctx.hook(event, handler)` and `ctx.trigger(event, ...args)`
106
- 5. **Logger**: Always use `ctx.logger` for consistent, structured logging
107
-
108
- **Common Plugin Pattern:**
109
- ```typescript
110
- const plugin: Plugin = {
111
- name: 'my-plugin',
112
- dependencies: ['other-plugin'], // Load after these plugins
113
-
114
- async init(ctx: PluginContext) {
115
- // Register services and hooks
116
- const otherService = ctx.getService('other-service');
117
- ctx.registerService('my-service', new MyService(otherService));
118
- ctx.hook('data:created', async (data) => { /* ... */ });
119
- },
120
-
121
- async start(ctx: PluginContext) {
122
- // Execute business logic
123
- const service = ctx.getService('my-service');
124
- await service.initialize();
125
- },
126
-
127
- async destroy() {
128
- // Cleanup resources
129
- await service.close();
130
- }
131
- };
132
- ```
133
-
134
- ## Configurable Logger
135
-
136
- The logger uses **[Pino](https://github.com/pinojs/pino)** for Node.js environments (high-performance, low-overhead) and a simple console-based logger for browsers. It automatically detects the runtime environment.
137
-
138
- ### Why Pino?
139
-
140
- - **Fast**: One of the fastest Node.js loggers available
141
- - **Low Overhead**: Minimal performance impact on your application
142
- - **Structured Logging**: Native JSON output for log aggregation tools
143
- - **Production Ready**: Battle-tested in production environments
144
- - **Feature Rich**: Automatic log rotation, transports, child loggers, and more
145
-
146
- ### Logger Configuration
18
+ ## Basic Usage
147
19
 
148
20
  ```typescript
149
- const kernel = new ObjectKernel({
150
- logger: {
151
- level: 'debug', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
152
- format: 'pretty', // 'json' | 'text' | 'pretty'
153
- sourceLocation: true, // Include file/line numbers
154
- redact: ['password', 'token', 'apiKey'], // Keys to redact
155
- file: './logs/app.log', // Node.js only
156
- rotation: { // File rotation (Node.js only)
157
- maxSize: '10m',
158
- maxFiles: 5
159
- }
160
- }
161
- });
162
- ```
21
+ import { ObjectKernel } from '@objectstack/core';
163
22
 
164
- ### Using Logger in Plugins
23
+ const kernel = new ObjectKernel();
165
24
 
166
- ```typescript
167
- const myPlugin: Plugin = {
25
+ // Register a simple plugin
26
+ kernel.use({
168
27
  name: 'my-plugin',
169
-
170
- init: async (ctx: PluginContext) => {
171
- // Basic logging
172
- ctx.logger.info('Plugin initialized');
173
- ctx.logger.debug('Debug info', { details: 'data' });
174
- ctx.logger.warn('Warning message');
175
- ctx.logger.error('Error occurred', new Error('Oops'));
176
-
177
- // Sensitive data is automatically redacted
178
- ctx.logger.info('User login', {
179
- username: 'john',
180
- password: 'secret123' // Logged as '***REDACTED***'
181
- });
182
- }
183
- };
184
- ```
185
-
186
- ### Standalone Logger
187
-
188
- ```typescript
189
- import { createLogger } from '@objectstack/core';
190
-
191
- const logger = createLogger({
192
- level: 'info',
193
- format: 'json'
194
- });
195
-
196
- logger.info('Application started');
197
-
198
- // Child logger with context
199
- const requestLogger = logger.child({
200
- requestId: '123',
201
- userId: 'user-456'
202
- });
203
-
204
- requestLogger.info('Processing request');
205
-
206
- // Distributed tracing
207
- const tracedLogger = logger.withTrace('trace-id-123', 'span-id-456');
208
-
209
- // Cleanup
210
- await logger.destroy();
211
- ```
212
-
213
- ## Log Formats
214
-
215
- ### JSON (default for Node.js)
216
- ```json
217
- {"timestamp":"2026-01-29T22:47:36.441Z","level":"info","message":"User action","context":{"userId":"123"}}
218
- ```
219
-
220
- ### Text
221
- ```
222
- 2026-01-29T22:47:36.441Z | INFO | User action | {"userId":"123"}
223
- ```
224
-
225
- ### Pretty (default for browser)
226
- ```
227
- [INFO] User action { userId: '123' }
228
- ```
229
-
230
- ## Plugin Development
231
-
232
- ```typescript
233
- import { Plugin, PluginContext } from '@objectstack/core';
234
-
235
- const databasePlugin: Plugin = {
236
- name: 'database',
237
28
  version: '1.0.0',
238
-
239
- init: async (ctx: PluginContext) => {
240
- const db = await connectToDatabase();
241
- ctx.registerService('db', db);
242
- ctx.logger.info('Database connected');
243
- },
244
-
245
- start: async (ctx: PluginContext) => {
246
- ctx.logger.info('Database ready');
247
- },
248
-
249
- destroy: async () => {
250
- await db.close();
251
- }
252
- };
253
-
254
- const apiPlugin: Plugin = {
255
- name: 'api',
256
- dependencies: ['database'], // Load after database
257
-
258
- init: async (ctx: PluginContext) => {
259
- const db = ctx.getService('db');
260
- const server = createServer(db);
261
- ctx.registerService('api', server);
262
- }
263
- };
264
-
265
- kernel.use(databasePlugin);
266
- kernel.use(apiPlugin);
267
- await kernel.bootstrap();
268
- ```
269
-
270
- ## Advanced Kernel Usage
271
-
272
- For production applications, use `ObjectKernel` (formerly `EnhancedObjectKernel`) for advanced features:
273
-
274
- ```typescript
275
- import { ObjectKernel, PluginMetadata, ServiceLifecycle } from '@objectstack/core';
276
-
277
- // Create kernel with advanced configuration
278
- const kernel = new ObjectKernel({
279
- logger: { level: 'info', format: 'pretty' },
280
- defaultStartupTimeout: 30000, // 30 seconds
281
- gracefulShutdown: true,
282
- shutdownTimeout: 60000, // 60 seconds
283
- rollbackOnFailure: true, // Rollback on failures
284
- });
285
-
286
- // Plugin with version and health check
287
- const plugin: PluginMetadata = {
288
- name: 'my-plugin',
289
- version: '1.2.3',
290
- startupTimeout: 10000,
291
-
292
29
  async init(ctx) {
293
- ctx.registerService('my-service', serviceInstance);
294
- },
295
-
296
- async healthCheck() {
297
- return {
298
- healthy: true,
299
- message: 'Service is operational'
300
- };
30
+ ctx.logger.info('Plugin initializing...');
301
31
  }
302
- };
303
-
304
- // Register service factory with lifecycle
305
- kernel.registerServiceFactory(
306
- 'database',
307
- async (ctx) => await connectToDatabase(),
308
- ServiceLifecycle.SINGLETON
309
- );
32
+ });
310
33
 
311
- await kernel.use(plugin);
312
34
  await kernel.bootstrap();
313
-
314
- // Check health
315
- const health = await kernel.checkPluginHealth('my-plugin');
316
- console.log(health);
317
-
318
- // Get metrics
319
- const metrics = kernel.getPluginMetrics();
320
- console.log(metrics);
321
-
322
- // Graceful shutdown
323
- await kernel.shutdown();
324
35
  ```
325
-
326
- See [ENHANCED_FEATURES.md](./ENHANCED_FEATURES.md) for comprehensive documentation.
327
- See [examples/enhanced-kernel-example.ts](./examples/enhanced-kernel-example.ts) for a complete example.
328
-
329
- ## Environment Support
330
-
331
- ### Node.js Features (via Pino)
332
- - High-performance structured logging
333
- - Automatic file logging with rotation
334
- - JSON format for log aggregation tools (Elasticsearch, Splunk, etc.)
335
- - Pretty printing for development (via pino-pretty)
336
- - Child loggers with inherited context
337
- - Minimal performance overhead
338
-
339
- ### Browser Features
340
- - Pretty console output with colors
341
- - DevTools integration
342
- - Lightweight implementation
343
- - No external dependencies
344
-
345
- ## Security
346
-
347
- Automatic sensitive data redaction:
348
- - Default keys: `password`, `token`, `secret`, `key`
349
- - Configurable via `redact` option
350
- - Recursive through nested objects
351
-
352
- ## API Reference
353
-
354
- ### LiteKernel (Minimal)
355
- - `LiteKernel` - Lightweight microkernel for serverless/test
356
- - `createLogger(config)` - Create standalone logger
357
- - `Plugin` - Plugin interface
358
- - `PluginContext` - Runtime context for plugins
359
- - `Logger` - Logger interface
360
-
361
- ### ObjectKernel (Production)
362
- - `ObjectKernel` - Full-featured enterprise microkernel
363
- - `PluginLoader` - Plugin loading and validation
364
- - `ServiceLifecycle` - Service lifecycle management (SINGLETON, TRANSIENT, SCOPED)
365
- - `PluginMetadata` - Extended plugin interface with metadata
366
- - `PluginHealthStatus` - Health check result interface
367
-
368
- See [TypeScript definitions](./src/types.ts) for complete API.
369
-
370
- ## Documentation
371
-
372
- - [ADVANCED_FEATURES.md](./ADVANCED_FEATURES.md) - Comprehensive guide to kernel features
373
- - [examples/kernel-features-example.ts](./examples/kernel-features-example.ts) - Complete working example
374
-
375
- ## License
376
-
377
- Apache-2.0
@@ -5,7 +5,9 @@ import { ApiRegistry } from './api-registry';
5
5
  describe('API Registry Plugin', () => {
6
6
  let kernel;
7
7
  beforeEach(() => {
8
- kernel = new ObjectKernel();
8
+ kernel = new ObjectKernel({
9
+ skipSystemValidation: true
10
+ });
9
11
  });
10
12
  describe('Plugin Registration', () => {
11
13
  it('should register API Registry as a service', async () => {
@@ -580,8 +580,8 @@ describe('ApiRegistry', () => {
580
580
  endpoints: [],
581
581
  });
582
582
  const snapshot = registry.getRegistry();
583
- expect(snapshot.byType?.rest.length).toBe(2);
584
- expect(snapshot.byType?.graphql.length).toBe(1);
583
+ expect(snapshot.byType?.rest?.length).toBe(2);
584
+ expect(snapshot.byType?.graphql?.length).toBe(1);
585
585
  });
586
586
  });
587
587
  describe('clear', () => {
@@ -1,4 +1,4 @@
1
- import type { SemanticVersion, VersionConstraint, CompatibilityLevel, DependencyConflict } from '@objectstack/spec/system';
1
+ import type { SemanticVersion, VersionConstraint, CompatibilityLevel, DependencyConflict } from '@objectstack/spec/kernel';
2
2
  import type { ObjectLogger } from './logger.js';
3
3
  /**
4
4
  * Semantic Version Parser and Comparator
@@ -1,4 +1,4 @@
1
- import type { PluginHealthStatus, PluginHealthCheck, PluginHealthReport } from '@objectstack/spec/system';
1
+ import type { PluginHealthStatus, PluginHealthCheck, PluginHealthReport } from '@objectstack/spec/kernel';
2
2
  import type { ObjectLogger } from './logger.js';
3
3
  import type { Plugin } from './types.js';
4
4
  /**
@@ -1,4 +1,4 @@
1
- import type { HotReloadConfig } from '@objectstack/spec/system';
1
+ import type { HotReloadConfig } from '@objectstack/spec/kernel';
2
2
  import type { ObjectLogger } from './logger.js';
3
3
  import type { Plugin } from './types.js';
4
4
  /**
package/dist/kernel.d.ts CHANGED
@@ -14,6 +14,8 @@ export interface ObjectKernelConfig {
14
14
  shutdownTimeout?: number;
15
15
  /** Whether to rollback on startup failure */
16
16
  rollbackOnFailure?: boolean;
17
+ /** Whether to skip strict system requirement validation (Critical for testing) */
18
+ skipSystemValidation?: boolean;
17
19
  }
18
20
  /**
19
21
  * Enhanced ObjectKernel with Advanced Plugin Management
@@ -49,10 +51,18 @@ export declare class ObjectKernel {
49
51
  * Register a plugin with enhanced validation
50
52
  */
51
53
  use(plugin: Plugin): Promise<this>;
54
+ /**
55
+ * Register a service instance directly
56
+ */
57
+ registerService<T>(name: string, service: T): this;
52
58
  /**
53
59
  * Register a service factory with lifecycle management
54
60
  */
55
61
  registerServiceFactory<T>(name: string, factory: ServiceFactory<T>, lifecycle?: ServiceLifecycle, dependencies?: string[]): this;
62
+ /**
63
+ * Validate Critical System Requirements
64
+ */
65
+ private validateSystemRequirements;
56
66
  /**
57
67
  * Bootstrap the kernel with enhanced features
58
68
  */
@@ -1 +1 @@
1
- {"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../src/kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAgC,gBAAgB,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAEzH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAE/B,qDAAqD;IACrD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA2E;IACxF,OAAO,CAAC,KAAK,CAAwE;IACrF,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,gBAAgB,CAAkC;gBAE9C,MAAM,GAAE,kBAAuB;IAyF3C;;OAEG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBxC;;OAEG;IACH,sBAAsB,CAAC,CAAC,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAC1B,SAAS,GAAE,gBAA6C,EACxD,YAAY,CAAC,EAAE,MAAM,EAAE,GACxB,IAAI;IAUP;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAqDhC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC/B;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzD;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAWxD;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIvC;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC;IAI9B;;OAEG;IACG,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,MAAM;YAMJ,qBAAqB;YAerB,sBAAsB;YA6CtB,sBAAsB;YAkBtB,eAAe;IA2B7B,OAAO,CAAC,mBAAmB;IAyC3B,OAAO,CAAC,uBAAuB;IA2B/B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAGjD"}
1
+ {"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../src/kernel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAgC,gBAAgB,EAAE,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAEzH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAE/B,qDAAqD;IACrD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,KAAK,CAA2E;IACxF,OAAO,CAAC,KAAK,CAAwE;IACrF,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,gBAAgB,CAAkC;gBAE9C,MAAM,GAAE,kBAAuB;IAoF3C;;OAEG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBxC;;OAEG;IACH,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI;IAUlD;;OAEG;IACH,sBAAsB,CAAC,CAAC,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAC1B,SAAS,GAAE,gBAA6C,EACxD,YAAY,CAAC,EAAE,MAAM,EAAE,GACxB,IAAI;IAUP;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAwClC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAsDhC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC/B;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzD;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAWxD;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIvC;;OAEG;IACH,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC;IAI9B;;OAEG;IACG,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,QAAQ,IAAI,MAAM;YAMJ,qBAAqB;YAerB,sBAAsB;YA6CtB,sBAAsB;YAkBtB,eAAe;IA2B7B,OAAO,CAAC,mBAAmB;IAyC3B,OAAO,CAAC,uBAAuB;IA2B/B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAGjD"}
package/dist/kernel.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { createLogger } from './logger.js';
2
+ import { ServiceRequirementDef } from '@objectstack/spec/system';
2
3
  import { PluginLoader, ServiceLifecycle } from './plugin-loader.js';
3
4
  /**
4
5
  * Enhanced ObjectKernel with Advanced Plugin Management
@@ -38,12 +39,7 @@ export class ObjectKernel {
38
39
  // Initialize context
39
40
  this.context = {
40
41
  registerService: (name, service) => {
41
- if (this.services.has(name)) {
42
- throw new Error(`[Kernel] Service '${name}' already registered`);
43
- }
44
- this.services.set(name, service);
45
- this.pluginLoader.registerService(name, service);
46
- this.logger.info(`Service '${name}' registered`, { service: name });
42
+ this.registerService(name, service);
47
43
  },
48
44
  getService: (name) => {
49
45
  // 1. Try direct service map first (synchronous cache)
@@ -125,6 +121,18 @@ export class ObjectKernel {
125
121
  });
126
122
  return this;
127
123
  }
124
+ /**
125
+ * Register a service instance directly
126
+ */
127
+ registerService(name, service) {
128
+ if (this.services.has(name)) {
129
+ throw new Error(`[Kernel] Service '${name}' already registered`);
130
+ }
131
+ this.services.set(name, service);
132
+ this.pluginLoader.registerService(name, service);
133
+ this.logger.info(`Service '${name}' registered`, { service: name });
134
+ return this;
135
+ }
128
136
  /**
129
137
  * Register a service factory with lifecycle management
130
138
  */
@@ -137,6 +145,44 @@ export class ObjectKernel {
137
145
  });
138
146
  return this;
139
147
  }
148
+ /**
149
+ * Validate Critical System Requirements
150
+ */
151
+ validateSystemRequirements() {
152
+ if (this.config.skipSystemValidation) {
153
+ this.logger.debug('System requirement validation skipped');
154
+ return;
155
+ }
156
+ this.logger.debug('Validating system service requirements...');
157
+ const missingServices = [];
158
+ const missingCoreServices = [];
159
+ // Iterate through all defined requirements
160
+ for (const [serviceName, criticality] of Object.entries(ServiceRequirementDef)) {
161
+ const hasService = this.services.has(serviceName) || this.pluginLoader.hasService(serviceName);
162
+ if (!hasService) {
163
+ if (criticality === 'required') {
164
+ this.logger.error(`CRITICAL: Required service missing: ${serviceName}`);
165
+ missingServices.push(serviceName);
166
+ }
167
+ else if (criticality === 'core') {
168
+ this.logger.warn(`CORE: Core service missing, functionality may be degraded: ${serviceName}`);
169
+ missingCoreServices.push(serviceName);
170
+ }
171
+ else {
172
+ this.logger.info(`Info: Optional service not present: ${serviceName}`);
173
+ }
174
+ }
175
+ }
176
+ if (missingServices.length > 0) {
177
+ const errorMsg = `System failed to start. Missing critical services: ${missingServices.join(', ')}`;
178
+ this.logger.error(errorMsg);
179
+ throw new Error(errorMsg);
180
+ }
181
+ if (missingCoreServices.length > 0) {
182
+ this.logger.warn(`System started with degraded capabilities. Missing core services: ${missingCoreServices.join(', ')}`);
183
+ }
184
+ this.logger.info('System requirement check passed');
185
+ }
140
186
  /**
141
187
  * Bootstrap the kernel with enhanced features
142
188
  */
@@ -174,6 +220,7 @@ export class ObjectKernel {
174
220
  }
175
221
  }
176
222
  // Phase 3: Trigger kernel:ready hook
223
+ this.validateSystemRequirements(); // Final check before ready
177
224
  this.logger.debug('Triggering kernel:ready hook');
178
225
  await this.context.trigger('kernel:ready');
179
226
  this.logger.info('✅ Bootstrap complete');
@@ -7,6 +7,7 @@ describe('ObjectKernel', () => {
7
7
  kernel = new ObjectKernel({
8
8
  logger: { level: 'error' }, // Suppress logs in tests
9
9
  gracefulShutdown: false, // Disable for tests
10
+ skipSystemValidation: true,
10
11
  });
11
12
  });
12
13
  describe('Plugin Registration and Loading', () => {
@@ -166,6 +167,7 @@ describe('ObjectKernel', () => {
166
167
  logger: { level: 'error' },
167
168
  rollbackOnFailure: false,
168
169
  gracefulShutdown: false,
170
+ skipSystemValidation: true,
169
171
  });
170
172
  let plugin1Destroyed = false;
171
173
  const plugin1 = {
@@ -128,6 +128,10 @@ export declare class PluginLoader {
128
128
  * Register a static service instance (legacy support)
129
129
  */
130
130
  registerService(name: string, service: any): void;
131
+ /**
132
+ * Check if a service is registered (either as instance or factory)
133
+ */
134
+ hasService(name: string): boolean;
131
135
  /**
132
136
  * Detect circular dependencies in service factories
133
137
  * Note: This only detects cycles in service dependencies, not plugin dependencies.
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../src/plugin-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../src/plugin-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,oBAAY,gBAAgB;IACxB,iDAAiD;IACjD,SAAS,cAAc;IACvB,4CAA4C;IAC5C,SAAS,cAAc;IACvB,sDAAsD;IACtD,MAAM,WAAW;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACnC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,MAAM;IAC1C,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAEhB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAE3B,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mCAAmC;IACnC,WAAW,CAAC,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE5C,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,yCAAyC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,eAAe,CAAwB;IAC/C,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,gBAAgB,CAA+C;IACvE,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,cAAc,CAA4C;IAClE,OAAO,CAAC,QAAQ,CAA0B;gBAE9B,MAAM,EAAE,MAAM;IAK1B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAIxC;;OAEG;IACH,kBAAkB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIlD;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiD3D;;OAEG;IACH,sBAAsB,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI;IAS/D;;OAEG;IACG,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IA8B/D;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;IAOjD;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC;;;;OAIG;IACH,0BAA0B,IAAI,MAAM,EAAE;IAoCtC;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkCxE;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKjC;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAM/C,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,yBAAyB;IAmBjC,OAAO,CAAC,sBAAsB;IAK9B,OAAO,CAAC,oBAAoB;YAgBd,qBAAqB;YAWrB,mBAAmB;YAanB,sBAAsB;YAMtB,gBAAgB;YAiBhB,qBAAqB;CAgBtC"}
@@ -127,6 +127,12 @@ export class PluginLoader {
127
127
  }
128
128
  this.serviceInstances.set(name, service);
129
129
  }
130
+ /**
131
+ * Check if a service is registered (either as instance or factory)
132
+ */
133
+ hasService(name) {
134
+ return this.serviceInstances.has(name) || this.serviceFactories.has(name);
135
+ }
130
136
  /**
131
137
  * Detect circular dependencies in service factories
132
138
  * Note: This only detects cycles in service dependencies, not plugin dependencies.
@@ -1,4 +1,4 @@
1
- import type { Permission, PermissionSet, PermissionAction, ResourceType } from '@objectstack/spec/system';
1
+ import type { Permission, PermissionSet, PermissionAction, ResourceType } from '@objectstack/spec/kernel';
2
2
  import type { ObjectLogger } from '../logger.js';
3
3
  /**
4
4
  * Permission Grant
@@ -1,5 +1,5 @@
1
1
  import type { Logger } from '@objectstack/spec/contracts';
2
- import type { PluginCapability } from '@objectstack/spec/system';
2
+ import type { PluginCapability } from '@objectstack/spec/kernel';
3
3
  import type { PluginContext } from '../types.js';
4
4
  /**
5
5
  * Plugin Permissions
@@ -1,4 +1,4 @@
1
- import type { SandboxConfig } from '@objectstack/spec/system';
1
+ import type { SandboxConfig } from '@objectstack/spec/kernel';
2
2
  import type { ObjectLogger } from '../logger.js';
3
3
  /**
4
4
  * Resource Usage Statistics
@@ -1,4 +1,4 @@
1
- import type { SecurityVulnerability, SecurityScanResult } from '@objectstack/spec/system';
1
+ import type { SecurityVulnerability, SecurityScanResult } from '@objectstack/spec/kernel';
2
2
  import type { ObjectLogger } from '../logger.js';
3
3
  /**
4
4
  * Scan Target
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@objectstack/core",
3
- "version": "0.9.2",
3
+ "version": "1.0.0",
4
+ "license": "Apache-2.0",
4
5
  "description": "Microkernel Core for ObjectStack",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
@@ -14,7 +15,7 @@
14
15
  "pino": "^8.17.0",
15
16
  "pino-pretty": "^10.3.0",
16
17
  "zod": "^4.3.6",
17
- "@objectstack/spec": "0.9.2"
18
+ "@objectstack/spec": "1.0.0"
18
19
  },
19
20
  "peerDependencies": {
20
21
  "pino": "^8.0.0"
@@ -9,7 +9,9 @@ describe('API Registry Plugin', () => {
9
9
  let kernel: ObjectKernel;
10
10
 
11
11
  beforeEach(() => {
12
- kernel = new ObjectKernel();
12
+ kernel = new ObjectKernel({
13
+ skipSystemValidation: true
14
+ });
13
15
  });
14
16
 
15
17
  describe('Plugin Registration', () => {
@@ -657,8 +657,8 @@ describe('ApiRegistry', () => {
657
657
  });
658
658
 
659
659
  const snapshot = registry.getRegistry();
660
- expect(snapshot.byType?.rest.length).toBe(2);
661
- expect(snapshot.byType?.graphql.length).toBe(1);
660
+ expect(snapshot.byType?.rest?.length).toBe(2);
661
+ expect(snapshot.byType?.graphql?.length).toBe(1);
662
662
  });
663
663
  });
664
664
 
@@ -3,7 +3,7 @@ import type {
3
3
  VersionConstraint,
4
4
  CompatibilityLevel,
5
5
  DependencyConflict
6
- } from '@objectstack/spec/system';
6
+ } from '@objectstack/spec/kernel';
7
7
  import type { ObjectLogger } from './logger.js';
8
8
 
9
9
  /**
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect, beforeEach } from 'vitest';
2
2
  import { PluginHealthMonitor } from './health-monitor.js';
3
3
  import { createLogger } from './logger.js';
4
- import type { PluginHealthCheck } from '@objectstack/spec/system';
4
+ import type { PluginHealthCheck } from '@objectstack/spec/kernel';
5
5
 
6
6
  describe('PluginHealthMonitor', () => {
7
7
  let monitor: PluginHealthMonitor;
@@ -2,7 +2,7 @@ import type {
2
2
  PluginHealthStatus,
3
3
  PluginHealthCheck,
4
4
  PluginHealthReport
5
- } from '@objectstack/spec/system';
5
+ } from '@objectstack/spec/kernel';
6
6
  import type { ObjectLogger } from './logger.js';
7
7
  import type { Plugin } from './types.js';
8
8
 
package/src/hot-reload.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type {
2
2
  HotReloadConfig,
3
3
  PluginStateSnapshot
4
- } from '@objectstack/spec/system';
4
+ } from '@objectstack/spec/kernel';
5
5
  import type { ObjectLogger } from './logger.js';
6
6
  import type { Plugin } from './types.js';
7
7
 
@@ -10,6 +10,7 @@ describe('ObjectKernel', () => {
10
10
  kernel = new ObjectKernel({
11
11
  logger: { level: 'error' }, // Suppress logs in tests
12
12
  gracefulShutdown: false, // Disable for tests
13
+ skipSystemValidation: true,
13
14
  });
14
15
  });
15
16
 
@@ -226,6 +227,7 @@ describe('ObjectKernel', () => {
226
227
  logger: { level: 'error' },
227
228
  rollbackOnFailure: false,
228
229
  gracefulShutdown: false,
230
+ skipSystemValidation: true,
229
231
  });
230
232
 
231
233
  let plugin1Destroyed = false;
package/src/kernel.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Plugin, PluginContext } from './types.js';
2
2
  import { createLogger, ObjectLogger } from './logger.js';
3
3
  import type { LoggerConfig } from '@objectstack/spec/system';
4
+ import { ServiceRequirementDef } from '@objectstack/spec/system';
4
5
  import { PluginLoader, PluginMetadata, ServiceLifecycle, ServiceFactory, PluginStartupResult } from './plugin-loader.js';
5
6
 
6
7
  /**
@@ -20,6 +21,9 @@ export interface ObjectKernelConfig {
20
21
 
21
22
  /** Whether to rollback on startup failure */
22
23
  rollbackOnFailure?: boolean;
24
+
25
+ /** Whether to skip strict system requirement validation (Critical for testing) */
26
+ skipSystemValidation?: boolean;
23
27
  }
24
28
 
25
29
  /**
@@ -67,12 +71,7 @@ export class ObjectKernel {
67
71
  // Initialize context
68
72
  this.context = {
69
73
  registerService: (name, service) => {
70
- if (this.services.has(name)) {
71
- throw new Error(`[Kernel] Service '${name}' already registered`);
72
- }
73
- this.services.set(name, service);
74
- this.pluginLoader.registerService(name, service);
75
- this.logger.info(`Service '${name}' registered`, { service: name });
74
+ this.registerService(name, service);
76
75
  },
77
76
  getService: <T>(name: string) => {
78
77
  // 1. Try direct service map first (synchronous cache)
@@ -167,6 +166,19 @@ export class ObjectKernel {
167
166
  return this;
168
167
  }
169
168
 
169
+ /**
170
+ * Register a service instance directly
171
+ */
172
+ registerService<T>(name: string, service: T): this {
173
+ if (this.services.has(name)) {
174
+ throw new Error(`[Kernel] Service '${name}' already registered`);
175
+ }
176
+ this.services.set(name, service);
177
+ this.pluginLoader.registerService(name, service);
178
+ this.logger.info(`Service '${name}' registered`, { service: name });
179
+ return this;
180
+ }
181
+
170
182
  /**
171
183
  * Register a service factory with lifecycle management
172
184
  */
@@ -185,6 +197,49 @@ export class ObjectKernel {
185
197
  return this;
186
198
  }
187
199
 
200
+ /**
201
+ * Validate Critical System Requirements
202
+ */
203
+ private validateSystemRequirements() {
204
+ if (this.config.skipSystemValidation) {
205
+ this.logger.debug('System requirement validation skipped');
206
+ return;
207
+ }
208
+
209
+ this.logger.debug('Validating system service requirements...');
210
+ const missingServices: string[] = [];
211
+ const missingCoreServices: string[] = [];
212
+
213
+ // Iterate through all defined requirements
214
+ for (const [serviceName, criticality] of Object.entries(ServiceRequirementDef)) {
215
+ const hasService = this.services.has(serviceName) || this.pluginLoader.hasService(serviceName);
216
+
217
+ if (!hasService) {
218
+ if (criticality === 'required') {
219
+ this.logger.error(`CRITICAL: Required service missing: ${serviceName}`);
220
+ missingServices.push(serviceName);
221
+ } else if (criticality === 'core') {
222
+ this.logger.warn(`CORE: Core service missing, functionality may be degraded: ${serviceName}`);
223
+ missingCoreServices.push(serviceName);
224
+ } else {
225
+ this.logger.info(`Info: Optional service not present: ${serviceName}`);
226
+ }
227
+ }
228
+ }
229
+
230
+ if (missingServices.length > 0) {
231
+ const errorMsg = `System failed to start. Missing critical services: ${missingServices.join(', ')}`;
232
+ this.logger.error(errorMsg);
233
+ throw new Error(errorMsg);
234
+ }
235
+
236
+ if (missingCoreServices.length > 0) {
237
+ this.logger.warn(`System started with degraded capabilities. Missing core services: ${missingCoreServices.join(', ')}`);
238
+ }
239
+
240
+ this.logger.info('System requirement check passed');
241
+ }
242
+
188
243
  /**
189
244
  * Bootstrap the kernel with enhanced features
190
245
  */
@@ -231,6 +286,7 @@ export class ObjectKernel {
231
286
  }
232
287
 
233
288
  // Phase 3: Trigger kernel:ready hook
289
+ this.validateSystemRequirements(); // Final check before ready
234
290
  this.logger.debug('Triggering kernel:ready hook');
235
291
  await this.context.trigger('kernel:ready');
236
292
 
@@ -246,6 +246,13 @@ export class PluginLoader {
246
246
  this.serviceInstances.set(name, service);
247
247
  }
248
248
 
249
+ /**
250
+ * Check if a service is registered (either as instance or factory)
251
+ */
252
+ hasService(name: string): boolean {
253
+ return this.serviceInstances.has(name) || this.serviceFactories.has(name);
254
+ }
255
+
249
256
  /**
250
257
  * Detect circular dependencies in service factories
251
258
  * Note: This only detects cycles in service dependencies, not plugin dependencies.
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect, beforeEach } from 'vitest';
2
2
  import { PluginPermissionManager } from './permission-manager.js';
3
3
  import { createLogger } from '../logger.js';
4
- import type { PermissionSet } from '@objectstack/spec/system';
4
+ import type { PermissionSet } from '@objectstack/spec/kernel';
5
5
 
6
6
  describe('PluginPermissionManager', () => {
7
7
  let manager: PluginPermissionManager;
@@ -3,7 +3,7 @@ import type {
3
3
  PermissionSet,
4
4
  PermissionAction,
5
5
  ResourceType
6
- } from '@objectstack/spec/system';
6
+ } from '@objectstack/spec/kernel';
7
7
  import type { ObjectLogger } from '../logger.js';
8
8
 
9
9
  /**
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect, beforeEach } from 'vitest';
2
2
  import { PluginPermissionEnforcer, SecurePluginContext } from './plugin-permission-enforcer.js';
3
3
  import { createLogger } from '../logger.js';
4
- import type { PluginCapability } from '@objectstack/spec/system';
4
+ import type { PluginCapability } from '@objectstack/spec/kernel';
5
5
  import type { PluginContext } from '../types.js';
6
6
 
7
7
  describe('PluginPermissionEnforcer', () => {
@@ -1,5 +1,5 @@
1
1
  import type { Logger } from '@objectstack/spec/contracts';
2
- import type { PluginCapability } from '@objectstack/spec/system';
2
+ import type { PluginCapability } from '@objectstack/spec/kernel';
3
3
  import type { PluginContext } from '../types.js';
4
4
 
5
5
  /**
@@ -1,6 +1,6 @@
1
1
  import type {
2
2
  SandboxConfig
3
- } from '@objectstack/spec/system';
3
+ } from '@objectstack/spec/kernel';
4
4
  import type { ObjectLogger } from '../logger.js';
5
5
 
6
6
  /**
@@ -1,7 +1,7 @@
1
1
  import type {
2
2
  SecurityVulnerability,
3
3
  SecurityScanResult
4
- } from '@objectstack/spec/system';
4
+ } from '@objectstack/spec/kernel';
5
5
  import type { ObjectLogger } from '../logger.js';
6
6
 
7
7
  /**